Today Button like this
Image of my pop-up calendar widget:
I am trying to create simple Gui using PyQt5 in Python with date picker option. I need to add today button in QDateEdit in pop-up QCalendarWidget.
You must add the button to the QCalendarWidget through the layout, and when the button is pressed set the QDate::currentDate() as selectedDate of the QCalendarWidget:
import sys
from PyQt5 import QtCore, QtWidgets
class DateEdit(QtWidgets.QDateEdit):
def __init__(self, parent=None):
super().__init__(parent, calendarPopup=True)
self._today_button = QtWidgets.QPushButton(self.tr("Today"))
self._today_button.clicked.connect(self._update_today)
self.calendarWidget().layout().addWidget(self._today_button)
#QtCore.pyqtSlot()
def _update_today(self):
self._today_button.clearFocus()
today = QtCore.QDate.currentDate()
self.calendarWidget().setSelectedDate(today)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = DateEdit()
w.show()
sys.exit(app.exec_())
You can decide to create a custom button to handle the popup even.
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class EditDate:
def __init__(self):
super(EditDate, self).__init__()
self.app_runner()
def date_gui(self):
self.app = QApplication(sys.argv)
self.win = QDialog()
self.win.setFixedSize(280, 40)
self.dateEdit = QDateEdit(self.win)
self.dateEdit.setFixedSize(230, 40)
self.dateEdit.move(5, 0)
self.hideCalendar = QPushButton(self.win)
self.hideCalendar.setText("Hide")
self.hideCalendar.move(231, 0)
self.hideCalendar.setFixedSize(45, 40)
self.displayCalendar = QPushButton(self.win)
self.displayCalendar.setText("Date..")
self.displayCalendar.move(231, 0)
self.displayCalendar.setFixedSize(45, 40)
self.calender = QCalendarWidget(self.win)
self.calender.move(5, 40)
self.todayButton = QPushButton(self.win)
self.todayButton.setText("Today")
self.todayButton.setFixedSize(100, 30)
self.todayButton.move(5, 200)
self.calender.hide()
self.todayButton.hide()
def button_handling(self):
self.todayButton.clicked.connect(self.todays_date)
self.displayCalendar.clicked.connect(self.display_cal)
self.hideCalendar.clicked.connect(self.hide_cal)
def hide_cal(self):
self.calender.hide()
self.displayCalendar.show()
self.todayButton.hide()
self.hideCalendar.hide()
self.win.setFixedSize(280, 40)
def display_cal(self):
self.win.setFixedSize(280, 300)
self.calender.show()
self.todayButton.show()
self.hideCalendar.show()
self.displayCalendar.hide()
def todays_date(self):
self.date = QDate.currentDate()
self.dateEdit.setDate(self.date)
self.calender.setSelectedDate(self.date)
def app_runner(self):
self.date_gui()
self.win.show()
self.button_handling()
sys.exit(self.app.exec_())
main = EditDate()
Related
I have a PyQt5 GUI application mainwindow that sets geometry based on the screen size. When I call the toogleLogWindow() function, the visibility property of hLayoutWidget_error changes, but window resize does not happen. When I restore the mainwindow manually by clicking the restore button on the right top corner, the resize function works. Can anyone help me understand this behavior? actionToggleLogWindow status is not checked by default.
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUI()
def setupUI(self):
# Set screen size parameters
for i in range(QApplication.desktop().screenCount()):
self.window_size = QApplication.desktop().availableGeometry(i).size()
self.resize(self.window_size)
self.move(QPoint(0, 0))
self._button = QtWidgets.QPushButton(self)
self._button.setText('Test Me')
self._editText = QtWidgets.QComboBox(self)
self._editText.setEditable(True)
self._editText.addItem("")
self._editText.setGeometry(QtCore.QRect(240, 40, 113, 21))
# Connect signal to slot
self._button.clicked.connect(self.toogleLogWindow)
def toogleLogWindow(self):
if self._editText.currentText() == "0":
h = self.window_size.height()
w = int(self.window_size.width()/2)
self.resize(w,h)
elif self._editText.currentText() == "1":
h = self.window_size.height()
w = int(self.window_size.width())
self.resize(w,h)
else:
pass
def get_main_app(argv=[]):
app = QApplication(argv)
win = MainWindow()
win.show()
return app, win
def main():
app, _win = get_main_app(sys.argv)
return app.exec_()
if __name__ == '__main__':
sys.exit(main())
It should be noted that:
It seems that if setting the maximum size of a window before being shown and then displaying it is equivalent to maximizing the window.
When a window is maximized you cannot change its size unless you return it to the previous state, for example if you change the size of the window manually until it is in the normal state then you can just change the size.
So there are several alternatives for this case:
Do not set the full size of the screen:
self.window_size = QApplication.desktop().availableGeometry(i).size() - QSize(10, 10)
Set the size after displaying:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUI()
def setupUI(self):
# Set screen size parameters
for i in range(QApplication.desktop().screenCount()):
self.window_size = QApplication.desktop().availableGeometry(i).size()
self._button = QPushButton(self)
self._button.setText("Test Me")
self._editText = QComboBox(self)
self._editText.setEditable(True)
self._editText.addItem("")
self._editText.setGeometry(QRect(240, 40, 113, 21))
# Connect signal to slot
self._button.clicked.connect(self.toogleLogWindow)
def init_geometry(self):
self.resize(self.window_size)
self.move(QPoint(0, 0))
def toogleLogWindow(self):
if self._editText.currentText() == "0":
h = self.window_size.height()
w = int(self.window_size.width() / 2)
self.resize(w, h)
elif self._editText.currentText() == "1":
h = self.window_size.height()
w = int(self.window_size.width())
self.resize(w, h)
else:
pass
def get_main_app(argv=[]):
app = QApplication(argv)
win = MainWindow()
win.show()
win.init_geometry()
return app, win
I am trying to make a window application in pyqt5 in which user enters a number then click("press me") button .
After that a number of rows are created according to the number entered by the user and one push button ("GO")
Each column has three labels with three textboxes
I managed to make the rows already , but what i can't manage is fetching the data from the textboxes when the push button is clicked
Note1: For simplicity , i was just trying the code for one textbox only then i will add more textboxes
Note2: i heard about some function called Lambda , but i searched for it and i couldn't find good explanation to it
Note3: Similar questions that didn't work for me:
Acessing dynamically added widgets I didn't know how to use this answer as i have two kinds of widgets in the layout , label and qlinedit
getting values from dynamically created qlinedits This answer didn't suit my case as i want one only button to get the data in all created textboxes
Code :
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5 import *
from PyQt5.QtWidgets import QLineEdit,QLabel,QGridLayout
import sys
class Window(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.home()
def home(self):
self.grid=QGridLayout()
self.setLayout(self.grid)
self.label=QLabel(self)
self.label.setText("NO")
self.grid.addWidget(self.label,0,1)
self.pushButton_ok = QtWidgets.QPushButton("Press me", self)
self.pushButton_ok.clicked.connect(self.addtextbox)
self.grid.addWidget(self.pushButton_ok,0,10)
self.input1=QLineEdit(self)
self.grid.addWidget(self.input1,0,5)
def addtextbox(self):
no_of_process=(self.input1.text())
no=int(no_of_process)
n=0
while(n<no):
self.bursttime=QLabel(self)
self.bursttime.setText("b")
self.timeinput=QLineEdit(self)
self.grid.addWidget(self.bursttime,2*n+1,0)
self.grid.addWidget(self.timeinput,2*n+1,1)
n=n+1
self.go=QtWidgets.QPushButton("GO",self)
self.grid.addWidget(self.go,6,0)
self.go.clicked.connect(self.printvalues)
def printvalues():
n=0
#fetch data in some way
application = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('Dynamically adding textboxes using a push button')
window.resize(250, 180)
window.show()
sys.exit(application.exec_())
Main Window of program
when user enters for example 2 to create 2 rows
Try it:
import sys
from PyQt5.QtWidgets import (QLineEdit, QLabel, QGridLayout, QWidget,
QPushButton, QApplication, QSpinBox)
class Window(QWidget):
def __init__(self):
super().__init__()
self.home()
def home(self):
self.grid = QGridLayout()
self.setLayout(self.grid)
self.label = QLabel(self)
self.label.setText("NO")
self.grid.addWidget(self.label, 0, 1)
# self.input1 = QLineEdit(self)
self.input1 = QSpinBox(self) # +++
self.input1.setMinimum(1)
self.input1.setMaximum(12)
self.input1.setValue(3)
self.grid.addWidget(self.input1, 0, 5)
self.pushButton_ok = QPushButton("Press me", self)
self.pushButton_ok.clicked.connect(self.addtextbox) #(self.addCheckbox)
self.grid.addWidget(self.pushButton_ok, 0, 10)
def addtextbox(self):
countLayout = self.layout().count()
if countLayout > 3:
for it in range(countLayout - 3):
w = self.layout().itemAt(3).widget()
self.layout().removeWidget(w)
w.hide()
self.lineEdits = [] # +++
for n in range(self.input1.value()):
self.bursttime = QLabel(self)
self.bursttime.setText("b_{}".format(n))
self.timeinput = QLineEdit(self)
self.timeinput.textChanged.connect(lambda text, i=n : self.editChanged(text, i)) # +++
self.grid.addWidget(self.bursttime, 2*n+1, 0)
self.grid.addWidget(self.timeinput, 2*n+1, 1)
self.lineEdits.append('') # +++
self.go = QPushButton("GO") #, self)
self.grid.addWidget(self.go, 2*n+2, 0)
self.go.clicked.connect(self.printvalues)
def printvalues(self):
# fetch data in some way
for i, v in enumerate(self.lineEdits): # +++
print("bursttime: b_{}, timeinput: {}".format(i, v)) # +++
def editChanged(self, text, i): # +++
self.lineEdits[i] = text # +++
def addCheckbox(self):
print("def addCheckbox(self):")
if __name__ == "__main__":
application = QApplication(sys.argv)
window = Window()
window.setWindowTitle('Dynamically adding textboxes using a push button')
window.resize(250, 180)
window.show()
sys.exit(application.exec_())
I was working on a PyQt5 app which had a dynamically loaded whole tab, with QTableView, QLineEdit and few QPushButtons, and had similar problem, I needed data from that one QLineEdit every tab. I've used QSignalMapper because I had to take data on textChanged() signal, but since you have a simple push button to just grab data, you can use QObject.findChildren() like I did in this example:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5 import *
from PyQt5.QtWidgets import QLineEdit,QLabel,QGridLayout
import sys
class Window(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.home()
def home(self):
self.grid=QGridLayout()
self.setLayout(self.grid)
self.label=QLabel(self)
self.label.setText("NO")
self.grid.addWidget(self.label,0,1)
self.pushButton_ok = QtWidgets.QPushButton("Press me", self)
self.pushButton_ok.clicked.connect(self.addtextbox)
self.grid.addWidget(self.pushButton_ok,0,10)
self.input1=QLineEdit(self)
self.grid.addWidget(self.input1,0,5)
def addtextbox(self):
no_of_process=(self.input1.text())
no=int(no_of_process)
n=0
while(n<no):
self.bursttime=QLabel(self)
self.bursttime.setText("b")
self.timeinput=QLineEdit(self)
self.timeinput.setObjectName("timeinput_{0}".format(n))
self.grid.addWidget(self.bursttime,2*n+1,0)
self.grid.addWidget(self.timeinput,2*n+1,1)
n=n+1
self.go=QtWidgets.QPushButton("GO",self)
self.grid.addWidget(self.go,6,0)
self.go.clicked.connect(self.printvalues)
def printvalues(self):
for child in self.findChildren(QLineEdit, QtCore.QRegExp("timeinput_(\d)+")):
print(child.text())
application = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('Dynamically adding textboxes using a push button')
window.resize(250, 180)
window.show()
sys.exit(application.exec_())
P.S. I fixed your pushButton_ok.clicked() signal, it was calling addCheckBox() which doesn't exist.
I am currently making an application with PyQt5 and I am trying to find a way to refresh the main window when the QWidget it calls is closed.
My main window page looks like this:
import sys
import glob
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from addClass import addClass
class TeacherMain(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.initUI()
def initUI(self):
x = 30
y = 80
buttonContainer = QLabel(self)
buttonContainer.setStyleSheet("background-color: #5D4A41;")
buttonContainer.move(20, 70)
buttonContainer.resize(1240, 550)
buttonContainer.show()
classes = glob.glob("Folder/*.csv")
classes = [j.strip("Folder/") for j in [i.strip('.csv') for i in classes]]
for k in classes:
classButton = QPushButton(k, self)
classButton.move(x, y)
classButton.setStyleSheet("background-color: green;")
classButton.resize(143, 143)
classButton.clicked.connect(self.viewClass)
x += 153 ## Increase value of x.
if x >= 1235:
y += 153
x = 30
addClass = QPushButton("Add Class...", self)
addClass.move(x, y)
addClass.resize(143, 143)
addClass.clicked.connect(self.createClass)
quit = QPushButton("Quit", self)
quit.setStyleSheet("background-color: white;")
quit.move(630, 645)
self.setStyleSheet("background-color: #AD9A90;")
self.setWindowTitle("SheikhCoin Teacher")
self.setFixedSize(1280, 690)
self.show()
def createClass(self):
self.new_window = addClass()
self.new_window.show()
def main():
app = QApplication(sys.argv)
main = TeacherMain()
main.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
And my QWidget looks like this:
class addClass(QWidget):
def __init__(self):
QWidget.__init__(self)
self.initUI()
def initUI(self, granted):
className = QLabel("Class Name", self)
className.setStyleSheet("font: 14pt Comic Sans MS")
self.nameBox = QLineEdit(self)
self.nameBox.resize(200, 20)
self.nameBox.setStyleSheet("background-color: white;")
add = QPushButton("Add Class", self)
add.setStyleSheet("background-color: white;")
add.clicked.connect()
def create(self):
name = self.nameBox.text()
path = "Folder/" + name + ".csv"
classRows = [["Student Key", "Prefix", "Forename", "Surname", "Tutor"]]
with open(path, 'w') as file:
write = csv.writer(newClass, delimiter=',')
write.writerows(classRows)
self.close()
Once the file is created in the QWidget, I would like the Main Window to update to show the file that has just been added as a button, as is done with the files already in Folder when the Main Window is first opened.
Anybody have any idea how to do this?
I am a beginner with GUI's and PYQT. What I am trying to do is dynamically set up a grid of QComboBox's and QLineEdit's. From the QComboBox you can select a choice and from that choice, it will fill in the corresponding QLineEdit with some numbers. The problem I'm having is creating the link between the first QComboBox and the first QLineEdit box. I could make a function for each row but I would like to know a better way. I will post some sample code. Thank you for any help or advice that you might have.
import sys
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(50, 50, 700, 600)
self.home()
def home(self):
Test1Choices = ['Test1:','Choice1', 'Choice2', 'Choice3', 'Choice4','Choice5', 'Choice6', 'Choice7', 'Choice8', 'Choice9']
Test2Choices= ['Test2:','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
for i in range(0,10):
Choice1ComboBox = QComboBox(self)
Choice1ComboBox.addItems(Test1Choices)
Choice1ComboBox.resize(150,25)
Choice1ComboBox.move(30,(150+(i*35)))
Choice1ComboBox.setCurrentIndex(2)
Choice2ComboBox = QComboBox(self)
Choice2ComboBox.setObjectName("Choice2ComboBox"+str(i))
Choice2ComboBox.addItems(Test2Choices)
Choice2ComboBox.resize(75,25)
Choice2ComboBox.move(200,(150+(i*35)))
Choice2ComboBox.setCurrentIndex(2)
Choice2ComboBox.activated[str].connect(self.doSomething)
numTextBox = QLineEdit(self)
numTextBox.setObjectName("numBox"+str(i))
numTextBox.move(325,(150+(i*35)))
numTextBox.resize(35,25)
result1TextBox = QLineEdit(self)
result1TextBox.setObjectName("result1Box"+str(i))
result1TextBox.move(400,(150+(i*35)))
result1TextBox.resize(100,25)
result1TextBox.setEnabled(0)
result2TextBox = QLineEdit(self)
result2TextBox.setObjectName("result2Box"+str(i))
result2TextBox.move(525,(150+(i*35)))
result2TextBox.resize(100,25)
result2TextBox.setEnabled(0)
self.show()
def doSomething(self):
numbers=['result1','result2','result3','result4','result5','result6','result7','result8','result9','result10','result11','result12','result13','result14','result15']
def run():
app = QApplication(sys.argv)
Gui = window()
sys.exit(app.exec_())
run()
To summarize I would like to bring in the index of the selected QComboBox. Then use that index number to reference the answer that is in the "numbers" array. Then print that result in the QLineEdit that is in the same row
We use sender() to get the object that emits the signal, then we look for the name of that object with setObjectName(), and we search the index, then we get the other objects with findChildren(), for example the output will be the union of the selected texts.
add name to Choice1ComboBox:
Choice1ComboBox.setObjectName("Choice1ComboBox"+str(i))
doSomething function:
def doSomething(self, _):
sender = self.sender()
l = sender.objectName().split("Choice1ComboBox")
if len(l) > 1:
number = l[1]
else:
number = sender.objectName().split("Choice2ComboBox")[1]
combo1 = self.findChildren(QComboBox, "Choice1ComboBox"+number)[0]
combo2 = self.findChildren(QComboBox, "Choice2ComboBox"+number)[0]
obj = self.findChildren(QLineEdit, "numBox"+number)[0]
obj.setText(combo1.currentText() + " " + combo2.currentText())
Complete code:
import sys
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(50, 50, 700, 600)
self.home()
def home(self):
Test1Choices = ['Test1:','Choice1', 'Choice2', 'Choice3', 'Choice4','Choice5', 'Choice6', 'Choice7', 'Choice8', 'Choice9']
Test2Choices= ['Test2:','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
for i in range(0,10):
Choice1ComboBox = QComboBox(self)
Choice1ComboBox.setObjectName("Choice1ComboBox"+str(i))
Choice1ComboBox.addItems(Test1Choices)
Choice1ComboBox.resize(150,25)
Choice1ComboBox.move(30,(150+(i*35)))
Choice1ComboBox.setCurrentIndex(2)
Choice1ComboBox.activated[str].connect(self.doSomething)
Choice2ComboBox = QComboBox(self)
Choice2ComboBox.setObjectName("Choice2ComboBox"+str(i))
Choice2ComboBox.addItems(Test2Choices)
Choice2ComboBox.resize(75,25)
Choice2ComboBox.move(200,(150+(i*35)))
Choice2ComboBox.setCurrentIndex(2)
Choice2ComboBox.activated[str].connect(self.doSomething)
numTextBox = QLineEdit(self)
numTextBox.setObjectName("numBox"+str(i))
numTextBox.move(325,(150+(i*35)))
numTextBox.resize(35,25)
result1TextBox = QLineEdit(self)
result1TextBox.setObjectName("result1Box"+str(i))
result1TextBox.move(400,(150+(i*35)))
result1TextBox.resize(100,25)
result1TextBox.setEnabled(0)
result2TextBox = QLineEdit(self)
result2TextBox.setObjectName("result2Box"+str(i))
result2TextBox.move(525,(150+(i*35)))
result2TextBox.resize(100,25)
result2TextBox.setEnabled(0)
self.show()
def doSomething(self, _):
sender = self.sender()
l = sender.objectName().split("Choice1ComboBox")
if len(l) > 1:
number = l[1]
else:
number = sender.objectName().split("Choice2ComboBox")[1]
combo1 = self.findChildren(QComboBox, "Choice1ComboBox"+number)[0]
combo2 = self.findChildren(QComboBox, "Choice2ComboBox"+number)[0]
obj = self.findChildren(QLineEdit, "numBox"+number)[0]
obj.setText(combo1.currentText() + " " + combo2.currentText())
def run():
app = QApplication(sys.argv)
Gui = window()
sys.exit(app.exec_())
run()
I have a browser application written in python with PySide Qt. But now I want to add a button in the toolbar to print the website. How do I do this? Because CTRL + P is not working in the application.
Here is the code:
import sys
from PySide import QtCore, QtGui, QtWebKit, QtHelp, QtNetwork
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
Action1 = QtGui.QAction('Google', self)
Action1.setShortcut('Ctrl+M')
Action1.triggered.connect(self.load_message)
self.toolbar1 = self.addToolBar('Google')
self.toolbar1.addAction(Action1)
Action2 = QtGui.QAction('Yahoo', self)
Action2.setShortcut('Ctrl+H')
Action2.triggered.connect(self.load_list)
self.toolbar2 = self.addToolBar('Yahoo')
self.toolbar2.addAction(Action2)
exitAction = QtGui.QAction('Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.triggered.connect(self.on_exit)
self.toolbar3 = self.addToolBar('Exit')
self.toolbar3.addAction(exitAction)
self.resize(750, 750)
self.setWindowTitle('Browser')
self.web = QtWebKit.QWebView(self)
self.web.load(QtCore.QUrl('http://www.google.com'))
self.setCentralWidget(self.web)
def on_exit(self):
QtGui.qApp.quit
def load_message(self):
self.web.load(QtCore.QUrl('http://www.google.com'))
def load_list(self):
self.web.load(QtCore.QUrl('http://www.yahoo.com'))
app = QtGui.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('myicon.ico'))
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
In your __init__ method add a Print action:
printAction = QtGui.QAction('Print', self)
printAction.setShortcut('Ctrl+P')
printAction.triggered.connect(self.do_print)
self.toolbar4 = self.addToolBar('Print')
self.toolbar4.addAction(printAction)
And create a do_print method:
def do_print(self):
p = QtGui.QPrinter()
p.setPaperSize(QtGui.QPrinter.A4)
p.setFullPage(True)
p.setResolution(300)
p.setOrientation(QtGui.QPrinter.Portrait)
p.setOutputFileName('D:\\test.pdf')
self.web.print_(p)
This will print to a file D:\test.pdf.
To configure your printer differently see the QPrinter documentation. Also if you want a print preview dialog see the QPrintPreviewDialog docs.
If you want a standard print dialog the use:
def do_print(self):
p = QtGui.QPrinter()
dialog = QtGui.QPrintDialog(p)
dialog.exec_()
self.web.print_(p)