How to open new window with push button [duplicate] - python

This question already has an answer here:
How to open a window with a click of a button from another window using PyQt?
(1 answer)
Closed 3 years ago.
How do I open a new window which allows me to select the time from the following code? I tried to use connect function to connect to windows2 however it appears that there is an error.
I would like to select time by a dropbox where I could choose time by 10 am, 11 am, ect.. Does anyone know how you could implement this as well?
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.label = QLabel()
self.calendar = QCalendarWidget()
self.title="Select date from calendar"
self.left = 600
self.top = 300
self.width = 500
self.height = 480
self.iconName = "home.png"
self.setWindowTitle(self.title)
self.setWindowIcon(QtGui.QIcon(self.iconName))
self.setGeometry(self.left, self.top, self.width, self.height)
self.proceedbutton = QPushButton("Proceed to select time", self)
self.proceedbutton.setGeometry(290, 430, 190, 40)
self.proceedbutton.setToolTip("<h3>Start the Session</h3>")
self.proceedbutton.clicked.connect(self.window2)
self.hide()
self.backbutton = QPushButton("Back", self)
self.backbutton.setGeometry(200, 430, 80, 40)
self.backbutton.setToolTip("<h3>Start the Session</h3>")
self.Calendar()
self.show()
def Calendar(self):
CalendarVbox = QVBoxLayout()
self.calendar.setGridVisible(True)
self.label.setFont(QtGui.QFont("Sanserif", 10))
self.label.setStyleSheet('color:black')
CalendarVbox.addWidget(self.calendar)
CalendarVbox.addWidget(self.label)
self.setLayout(CalendarVbox)
self.calendar.selectionChanged.connect(self.onSelectionChanged)
def window2(self):
self.label = QLabel("Select Time", self)
self.label.move(200,430)
self.setWindowTitle("Select Time")
self.setGeometry(self.left, self.top, self.width, self.height)
self.show()
def onSelectionChanged(self):
ca = self.calendar.selectedDate()
self.label.setText(ca.toString())
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

Start using layouts!
A widget without a parent - there is a window.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Window(QWidget): #(QMainWindow):
def __init__(self):
super().__init__()
self.title="Select date from calendar"
self.left, self.top, self.width, self.height = 600, 100, 500, 480
self.iconName = "Ok.png" # <--- home.png
self.setWindowTitle(self.title)
self.setWindowIcon(QtGui.QIcon(self.iconName))
self.setGeometry(self.left, self.top, self.width, self.height)
self.calendar = QCalendarWidget()
self.calendar.setGridVisible(True)
self.calendar.selectionChanged.connect(self.onSelectionChanged)
self.label = QLabel()
self.label.setFont(QtGui.QFont("Sanserif", 10))
self.label.setStyleSheet('color: blue;')
self.proceedbutton = QPushButton("Proceed to select time", self)
self.proceedbutton.setToolTip("<h3>Start the Session</h3>")
self.proceedbutton.clicked.connect(self.window2)
self.backbutton = QPushButton("Back", self)
self.backbutton.setToolTip("<h3>Start the Session</h3>")
self.comboBox = None
self.grid = QtWidgets.QGridLayout(self)
self.grid.addWidget(self.calendar, 0, 0, 1, 3)
self.grid.addWidget(self.label, 1, 0, 1, 3)
self.grid.addWidget(self.backbutton, 2, 1, 1, 1)
self.grid.addWidget(self.proceedbutton, 2, 2, 1, 1)
def window2(self):
self.window = QWidget()
self.window.setWindowTitle("Select Time")
self.window.setGeometry(self.left/3, self.top, self.width/3, self.height/3)
self.label = QLabel("Select Time") # --- , self)
self.comboBox = QtWidgets.QComboBox()
self.comboBox.addItems(["choose time", "10", "11", "12"])
self.comboBox.activated[str].connect(self.onComboActivated)
layout = QFormLayout(self.window)
layout.addRow('Choose Time', self.comboBox)
self.window.show()
def onSelectionChanged(self):
ca = self.calendar.selectedDate()
self.label.setText(ca.toString())
def onComboActivated(self, text):
print("choose time: {}".format(text))
if __name__ == '__main__':
App = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(App.exec())

Related

Can I use a variable from a function that's inside of another class?

What I'm trying to do is create 1 window with 8 check boxes. The user will click the ones that are relevant and press "Calculate Job". That button should then open a new window that contains buttons/sections/whatever for only the options that were selected in window 1. Sounds ok... I have window 1 set up in class First. When I click the button it shows up the new window, great! But now I need to find a way to say "If any of these sections are selected then do something in window 2".
code:
from PyQt5 import QtWidgets
import sys
import qdarkstyle
class First(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(First, self).__init__(parent)
self.title = 'Job Price Calculator'
self.left = 100
self.top = 100
self.width = 320
self.height = 350
self.initUI()
self.dialog = Second()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.data_processing = QtWidgets.QCheckBox('Data Processing', self)
self.data_processing.move(50, 50)
self.digital_print = QtWidgets.QCheckBox('Digital Print', self)
self.digital_print.move(50, 100)
self.calculate = QtWidgets.QPushButton('Calculate Job', self)
self.calculate.move(100, 250)
self.calculate.clicked.connect(self.on_button_click)
def on_button_click(self):
self.dialog.show()
class Second(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
self.title = 'Job Specification'
self.left = 500
self.top = 100
self.width = 1080
self.height = 920
self.initUI_specification()
def initUI_specification(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
if self.data_processing.isChecked():
self.data_processing_info()
if self.digital_print.isChecked():
self.digital_print_info()
def data_processing_info(self):
self.temp_button = QtWidgets.QPushButton('Temp Button', self)
self.temp_button.move(100, 250)
def digital_print_info(self):
self.temp_button2 = QtWidgets.QPushButton('Temp Button 2', self)
self.temp_button2.move(100, 450)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
So what I want to do in class 'Second' is use the checkbox variable of self.data_processing to check if it has been enabled, if it has then I want to pull up a button in the Second gui window.
Is what I'm trying to do possible? Should I be thinking of a different way to do this? I'd like someones opinion on this if possible, and a little bit of guidance. I'd really appreciate the help, I've spent my whole weekend messing around with this and I'm just getting nowhere.
You need to call your second class inside first class when your checkbox is clicked
from PyQt5 import QtWidgets
import sys
import qdarkstyle
class First(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(First, self).__init__(parent)
self.title = 'Job Price Calculator'
self.left = 100
self.top = 100
self.width = 320
self.height = 350
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.data_processing = QtWidgets.QCheckBox('Data Processing', self)
self.data_processing.move(50, 50)
self.data_processing.stateChanged.connect(self.checkbox_clicked)
self.digital_print = QtWidgets.QCheckBox('Digital Print', self)
self.digital_print.move(50, 100)
self.calculate = QtWidgets.QPushButton('Calculate Job', self)
self.calculate.move(100, 250)
self.calculate.clicked.connect(self.on_button_click)
self.secondClass = Second()
def on_button_click(self):
self.dialog.show()
def checkbox_clicked(self):
if self.data_processing.isChecked():
self.secondClass.data_processing_info()
self.secondClass.show()
else:
self.secondClass.hide() #hide or close - as your requirement
class Second(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
self.title = 'Job Specification'
self.left = 500
self.top = 100
self.width = 1080
self.height = 920
self.initUI_specification()
def initUI_specification(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
def data_processing_info(self):
self.temp_button = QtWidgets.QPushButton('Temp Button', self)
self.temp_button.move(100, 250)
def digital_print_info(self):
self.temp_button2 = QtWidgets.QPushButton('Temp Button 2', self)
self.temp_button2.move(100, 450)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())

How can I maintain the ability to type after using QLineEdit.selectAll?

I want users of my app to be able to press the button, and then keep typing. With QLineEdit.selectAll(), I am able to select the text entered after Run is pressed, but typing won't do anything. See:
The text is selected due to QLineEdit.selectAll(), but typing won't do anything.
Here's what I have so far:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.title = 'window title'
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.setCentralWidget(widget)
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
response = QLabel(self.line.text())
self.layout.addWidget(response)
self.line.selectAll()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
selectAll() is tricky. It looks like the widget has the focus, but it doesn't. Use setFocus(). Order doesn't matter in this case
self.line.setFocus()
self.line.selectAll()
or
self.line.selectAll()
self.line.setFocus()
Further, in this UI, you can hook up the returnPressed signal of self.line to on_click so that when the user presses enter/return in self.line, the on_click method runs.
self.line.returnPressed.connect(self.on_click)
Putting it all together:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel()
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.line.returnPressed.connect(self.on_click)
reset_button.clicked.connect(self.reset_click)
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text())
self.line.setFocus()
self.line.selectAll()
def reset_click(self):
self.label.setText('')
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
By using this:
self.line.selectAll()
self.line.grabKeyboard()
It will select the text entered at every push of the button, and you will be able to continue typing without clicking in the textbox.

How do I remove QLabels created iteratively?

I'm making an app where I'm iteratively creating QLabel. I'm trying to remove them with another button.
I want to remove the 'history'. I have tried different things like label.remove() and so on, but it would add no value to add my previous attempts here (also my attempts weren't on this reproducible example).
Here's the code that I have:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
response = QLabel(self.line.text())
self.layout.addWidget(response)
self.line.selectAll()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
You have to store the QLabels to later remove them from the layout and delete them, and then additionally recalculate the size of the window:
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel("Enter a WORD:")
run_button = QPushButton("Run")
reset_button = QPushButton("Reset History")
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.add_history)
reset_button.clicked.connect(self.delete_history)
self.setCentralWidget(widget)
self._history_labels = []
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def add_history(self):
history = QLabel(self.line.text())
self.layout.addWidget(history)
self.line.selectAll()
self._history_labels.append(history)
def delete_history(self):
for history in self._history_labels:
self.layout.removeWidget(history)
history.deleteLater()
self._history_labels = []
width = self.size().width()
self.adjustSize()
height = self.sizeHint().height()
QTimer.singleShot(0, lambda: self.resize(width, height))
To me, it would be easier to use one label to store all of your responses. Every time you hit "Run" button, append a new line to your label. Changed lines highlighted with # <---
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel() # <-----
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label) # <-----
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
reset_button.clicked.connect(self.reset_click) # <-----
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text()) # <-----
self.line.selectAll()
def reset_click(self): # <-----
self.label.setText('') # <-----
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel() # <-----
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label) # <-----
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
reset_button.clicked.connect(self.reset_click) # <-----
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text()) # <-----
self.line.selectAll()
def reset_click(self): # <-----
self.label.setText('') # <-----
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

Clear Button PyQt5

I have been trying to build a simple GUI with:
A QLineEdit where the user writes a string
A QPushButton that clears whatever the user writes in the above lineedit every time I click on it.
My issue is in the second one. I have been trying to solve it by looking at solutions online but they weren't really useful so far. Can anyone give a hint on how to proceed?
Here is my code:
import sys
from PyQt5.QtWidgets import QWidget, QLineEdit
from PyQt5.QtWidgets import QLabel, QPushButton, QApplication
from PyQt5.QtCore import pyqtSlot
app = QApplication(sys.argv)
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'MyApp'
self.left = 10
self.top = 10
self.width = 800
self.height = 800
self.initUI()
self.show()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Create textbox for index number 1
self.nameLabel = QLabel(self)
self.nameLabel.setText('Insert something:')
self.nameLabel.move(20, 80)
self.textbox_index1 = QLineEdit(self)
self.textbox_index1.move(20, 100)
self.textbox_index1.resize(280, 40)
# Create a button in the window
self.buttonC1 = QPushButton('Clear', self)
self.buttonC1.move(300, 119)
# connect buttons "CLEAR" to function
self.buttonC1.clicked.connect(self.on_clickC1)
#pyqtSlot()
# Functions for the CLEAR buttons
def on_clickC1(self):
self.x1 = clearSearch1(self.textbox_index1.text(''))
return self.x1
def clearSearch1(self.x):
return self.x.clear()
if __name__ == '__main__':
app.aboutToQuit.connect(app.deleteLater)
ex = App()
sys.exit(app.exec_())
Thanks so much in advance,
Mattia
I do not understand what you are trying to do, the solution is simple, you must connect the clicked signal to the clear method directly without creating any other function:
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'MyApp'
self.left, self.top, self.width, self.height = 10, 10, 800, 800
self.initUI()
self.show()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Create textbox for index number 1
self.nameLabel = QLabel(self)
self.nameLabel.setText('Insert something:')
self.nameLabel.move(20, 80)
self.textbox_index1 = QLineEdit(self)
self.textbox_index1.move(20, 100)
self.textbox_index1.resize(280, 40)
# Create a button in the window
self.buttonC1 = QPushButton('Clear', self)
self.buttonC1.move(300, 119)
# connect buttons "CLEAR" to function
self.buttonC1.clicked.connect(self.textbox_index1.clear)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

Updating PyQT label

I'm attempting to use a timer for scheduling to update certain values across the grid. Below is the example where I am attempting to update a label based on a timed event. I've successfully gotten it to call the function but I cannot update the label. Any thoughts?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtCore, QtGui, QtWidgets
class App(QWidget):
def __init__(self):
super().__init__() #these values change where the main window is placed
self.title = 'This is my title'
self.left = 400
self.top = 400
self.width = 300
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# call the gridlayout function
self.createGridLayout()
self.time_label.text = 'change the value'
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.horizontalGroupBox)
self.setLayout(windowLayout)
self.show() #this sets the main window to the screen size
def createGridLayout(self):
time = self.getTime()
self.time_label = QLabel(time, self)
self.horizontalGroupBox = QGroupBox()
layout = QGridLayout()
layout.addWidget(QPushButton('1'),0,0)
layout.addWidget(QPushButton(time),0,1)
layout.addWidget(self.time_label,0,2)
self.horizontalGroupBox.setLayout(layout)
def getTime(self):
time = QTime.currentTime().toString()
return time
def updateTime():
App.time = QTime.currentTime().toString()
time = QTime.currentTime().toString()
print("Time: " + time)
# self.time_label = 'change the value'
# self..layout.time_label = 'asdf'
return time
def main():
app = QApplication(sys.argv)
ex = App()
timer=QtCore.QTimer()
timer.timeout.connect(App.updateTime)
timer.start(1000)
sys.exit(app.exec_())
if __name__ == '__main__':
# App.main()
main()
Your code has some errors, if you want to use an attribute of the class with the reserved word self, this method must be a method of the class, for this it changes:
def updateTime():
to
def updateTime(self):
If you want to change the text of a QLabel you must use its setText().
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class App(QWidget):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent) # these values change where the main window is placed
self.title = 'This is my title'
self.left = 400
self.top = 400
self.width = 300
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# call the gridlayout function
self.createGridLayout()
self.time_label.text = 'change the value'
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.horizontalGroupBox)
self.setLayout(windowLayout)
self.show() # this sets the main window to the screen size
def createGridLayout(self):
time = self.getTime()
self.time_label = QLabel(time, self)
self.horizontalGroupBox = QGroupBox()
layout = QGridLayout()
layout.addWidget(QPushButton('1'), 0, 0)
layout.addWidget(QPushButton(time), 0, 1)
layout.addWidget(self.time_label, 0, 2)
self.horizontalGroupBox.setLayout(layout)
def getTime(self):
time = QTime.currentTime().toString()
return time
def updateTime(self):
time = QTime.currentTime().toString()
print("Time: " + time)
self.time_label.setText(time)
return time
def main():
app = QApplication(sys.argv)
ex = App()
timer = QTimer()
timer.timeout.connect(ex.updateTime)
timer.start(1000)
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Categories