check if button clicked or not in pyqt5 - python

Hello guys I want to check if the button clicked or not
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi("app.ui", self)
self.setWindowIcon(QIcon('discord.png'))
self.setWindowFlag(Qt.WindowMinimizeButtonHint, False)
self.setWindowFlag(Qt.WindowMaximizeButtonHint, False)
self.setFixedSize(self.size())
self.regis = self.findChild(QPushButton, "pushButton")
self.regis.clicked.connect(self.connectt)
self.cl = self.findChild(QPushButton, "pushButton_2")
self.show()
QApplication.processEvents()
def connectt(self):
ID = self.findChild(QLineEdit, "lineEdit")
RP = Presence(ID.text())
RP.connect()
print("connected")
self.statusBar.showMessage('connected')
if self.cl.clicked():
print("disconnected")
app = QApplication(sys.argv)
UIWindow = MainWindow()
app.exec_()
I tried to use self.cl.clicked() but it didn't work!
but I got this error :
if self.cl.clicked():
^^^^^^^^^^^^^^^^^
TypeError: native Qt signal is not callable
can anyone help me, please

You don't need your "if self.cl.clicked():
Assuming "regis" is your button, this line :
self.regis.clicked.connect(self.connectt)
makes it that as soon as you click your "regis" button, the whole "connectt" function will execute.
And if "cl" is another button, your code makes no sense to me, because what your doing is you verify if your "cl" button is clicked when you click your "regis" button (basically clicking two buttons at the same time, which feels strange in my opinion). Maybe you should think about another way to do what you're trying to do.
Let me know if this answered your question.
Edit:
You can use the codeblock like:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi("app.ui", self)
self.setWindowIcon(QIcon('discord.png'))
self.setWindowFlag(Qt.WindowMinimizeButtonHint, False)
self.setWindowFlag(Qt.WindowMaximizeButtonHint, False)
self.setFixedSize(self.size())
self.pushButton.clicked.connect(self.pushButtonOperations)
self.pushButton_2.clicked.connect(self.pushButton_2Operations)
self.cl = self.findChild(QPushButton, "pushButton_2")
self.show()
QApplication.processEvents()
def pushButtonOperations(self):
ID = self.findChild(QLineEdit, "lineEdit")
RP = Presence(ID.text())
RP.connect()
print("connected")
self.statusBar.showMessage('connected')
def pushButton_2Operations(self):
print("disconnected")
app = QApplication(sys.argv)
UIWindow = MainWindow()
app.exec_()

Related

Using 3 Buttons in PyQt5 DialogButtonBox

I'm attempting to create a Login System type dialog box for practice using PyQt5 (I'm quite new to the module) and i'm trying to give the user the ability to click (Ok, Cancel, Apply) as the buttons underneath inputs boxes for Username / Password, but i'm not sure how I can actually get the apply button to work. I have buttons.accepted.connect(*method*) and buttons.rejected.connect(*method*) but I don't know how to specify the pressing of the accept button. I have tried using buttons.clicked(dlgButtons[0] (Which is where the button is stored) but it just gives me an error.
The code below is my declaration of the buttons if that helps. Thanks
buttons = qt.QDialogButtonBox()
dlgButtons = (qt.QDialogButtonBox.Apply, qt.QDialogButtonBox.Ok, qt.QDialogButtonBox.Cancel)
buttons.setStandardButtons(
dlgButtons[0] | dlgButtons[1] | dlgButtons[2]
)
One possible solution might look like this:
from PyQt5.QtWidgets import *
class ModelessDialog(QDialog):
def __init__(self, part, threshold, parent=None):
super().__init__(parent)
self.setWindowTitle("Baseline")
self.setGeometry(800, 275, 300, 200)
self.part = part
self.threshold = threshold
self.threshNew = 4.4
label = QLabel("Part : {}\nThreshold : {}".format(
self.part, self.threshold))
self.label2 = QLabel("ThreshNew : {:,.2f}".format(self.threshNew))
self.spinBox = QDoubleSpinBox()
self.spinBox.setMinimum(-2.3)
self.spinBox.setMaximum(99)
self.spinBox.setValue(self.threshNew)
self.spinBox.setSingleStep(0.02)
self.spinBox.valueChanged.connect(self.valueChang)
buttonBox = QDialogButtonBox(
QDialogButtonBox.Ok
| QDialogButtonBox.Cancel
| QDialogButtonBox.Apply)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(self.label2)
layout.addWidget(self.spinBox)
layout.addWidget(buttonBox)
self.resize(300, 200)
self.setLayout(layout)
okBtn = buttonBox.button(QDialogButtonBox.Ok)
okBtn.clicked.connect(self._okBtn)
cancelBtn = buttonBox.button(QDialogButtonBox.Cancel)
cancelBtn.clicked.connect(self.reject)
applyBtn = buttonBox.button(QDialogButtonBox.Apply) # +++
applyBtn.clicked.connect(self._apply) # +++
def _apply(self): # +++
print('Hello Apply')
def _okBtn(self):
print("""
Part : {}
Threshold : {}
ThreshNew : {:,.2f}""".format(
self.part, self.threshold, self.spinBox.value()))
def valueChang(self):
self.label2.setText("ThreshNew : {:,.2f}".format(self.spinBox.value()))
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
button = QPushButton('Open Dialog', self)
button.clicked.connect(self.showDialog)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(button)
self.setLayout(layout)
def showDialog(self):
self.dialog = ModelessDialog(2, 55.77, self)
self.dialog.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(300, 200)
win.show()
sys.exit(app.exec_())
What you are storing in the dlgButtons is just a list of enums, specifically the StandardButton enum, which is a list of identifiers for the buttons, they are not the "actual" buttons.
Also, you cannot use the clicked signal like this:
buttons.clicked(dlgButtons[0])
That will generate a crash, as signals are not callable. The argument of the clicked() signal is what will be received from the slot, which means that if you connect a function to that signal, the function will receive the clicked button:
buttons.clicked.connect(self.buttonsClicked)
def buttonsClicked(self, button):
print(button.text())
The above will print the text of the clicked button (Ok, Apply, Cancel, or their equivalent localized text).
What you're looking for is to connect to the clicked signals of the actual buttons, and you can get the individual reference to each button by using the button() function:
applyButton = buttons.button(qt.QDialogButtonBox.Apply)
applyButton.clicked.connect(self.applyFunction)

How to get a PyQt5 QPushButton to do different commands on different button clicks

I wish to have the QPushButton do different things on different clicks. One the first click it should execute one command and on the next click, it should execute the other command. I've tried to make a program to do it but it only executes one command, not the other
my code I:
import PyQt5.QtWidgets as pyqt
import sys
ongoing = False
class Stuff(pyqt.QWidget):
def __init__(self):
super().__init__()
self.windows()
def windows(self):
w = pyqt.QWidget()
layout = pyqt.QGridLayout()
self.setLayout(layout)
button = pyqt.QPushButton('click me', w)
layout.addWidget(button)
if not ongoing:
button.clicked.connect(click_one)
else:
button.clicked.connect(click_two)
self.show()
w.show()
def click_one():
global ongoing
print('one')
ongoing = not ongoing
def click_two():
global ongoing
print('two')
ongoing = not ongoing
if __name__ == '__main__':
app = pyqt.QApplication(sys.argv)
x = Stuff()
app.exec_()
What should I do to fix this?
Since the value of ongoing is False when the class is initialized, the button's clicked signal gets connected to click_one(). Connect the button to an initial slot and then call the desired function based on the value of ongoing.
class Stuff(pyqt.QWidget):
def __init__(self):
super().__init__()
self.windows()
def windows(self):
w = pyqt.QWidget()
layout = pyqt.QGridLayout()
self.setLayout(layout)
button = pyqt.QPushButton('click me', w)
layout.addWidget(button)
button.clicked.connect(on_click)
self.show()
w.show()
def on_click():
global ongoing
if not ongoing:
click_one()
else:
click_two()
I suggest rewriting the code with the functions and ongoing variable belonging to the class. The QWidget assigned to variable w seems redundant because the QPushButton is then added to the layout of the class, so its parent gets changed anyways.
class Stuff(pyqt.QWidget):
def __init__(self):
super().__init__()
self.ongoing = False
self.windows()
def windows(self):
layout = pyqt.QGridLayout(self)
button = pyqt.QPushButton('click me')
layout.addWidget(button)
button.clicked.connect(self.on_click)
self.show()
def on_click(self):
self.click_one() if not self.ongoing else self.click_two()
self.ongoing = not self.ongoing
def click_one(self):
print('one')
def click_two(self):
print('two')
Also you might be interested in using a checkable button.

revert rejected dialogue/form to show last accepted values on reopen

I'm setting up an "options" dialog in a program, where I can change some values and close the dialog with Ok/Cancel to accept of reject my changes. After closing the dialog with cancel and reopening it, i would like the last accepted values to be displayed, however I am know sure how to implement this.
Below is a very simplified version of my code. I chose to instanciate the dialog only once (as opposed to creating a new instance each time I call the dialog), mainly to avoid having to call the __init__ and import data from save files each time I open the dialog.
from PyQt5.QtWidgets import QMainWindow, QPushButton,\
QApplication, QTextEdit, QDialog, QDialogButtonBox
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
btn = QPushButton('open text 1', self)
btn.move(10, 10)
btn.clicked.connect(self.open_dlg)
self.txtdlg = TextDialog()
def open_dlg(self):
if self.txtdlg.exec_() == QDialog.Accepted:
print(self.txtdlg.preferences)
class TextDialog(QDialog):
def __init__(self):
super().__init__()
self.preferences = "text here"
self.resize(200, 150)
self.textedit = QTextEdit(self)
self.textedit.resize(200, 100)
self.textedit.setText(self.preferences)
btns = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
btns.move(20, 100)
btns.accepted.connect(self.save_and_close)
btns.rejected.connect(self.reject)
def save_and_close(self):
self.preferences = self.textedit.toPlainText()
self.accept()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
MW = MainWindow()
MW.show()
sys.exit(app.exec_())
As it is, after clicking Cancel the dialog keeps any unsaved changes to its widgets if I reopen it. My fist idea was to connect the cancel button to a close_without_saving method that updates the dialog to the last saved values before closing, but the displayed values will not be up to date if preferences is changed for some reason while the dialog is invisible. Can I run some code when i call exec_ ? Or is the logic behind my implementation wrong somehow?
You have to implement a method that sets the values of the dialog to the default values:
# ...
class MainWindow(QMainWindow):
# ...
def open_dlg(self):
self.txtdlg.reset()
if self.txtdlg.exec_() == QDialog.Accepted:
print(self.txtdlg.preferences)
class TextDialog(QDialog):
# ...
def reset(self):
self.preferences = "text here"
self.textedit.setText(self.preferences)
def save_and_close(self):
self.preferences = self.textedit.toPlainText()
self.accept()
# ...

How to get result from corfirmation dialog

I have problem with the results of my pop-up window. Below I have shown part of my code to understand the problem.
It's a kind of pop-up window where the user makes some choice in the GUI. After this it should show a window where there will be the question "Are you sure?", and two buttons "Yes" and "No".
The problem is that when I test the code below (before and after the msg.show()), I have the same value set as False.
Why doesnt it work like this:
Before function -> False
Show my window and wait to click the button
If I clicked button "Yes", then give True, else False
How I can handle this properly? Is there another approach?
from PyQt4 import QtCore, QtGui
from Message import Ui_Message
import sys
class MessageBox(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent=None)
self.msg = Ui_Message()
self.msg.setupUi(self)
self.confirmed=False
self.declined=False
QtCore.QObject.connect(self.msg.NoButton, QtCore.SIGNAL(("clicked()")), self.Declined)
QtCore.QObject.connect(self.msg.YesButton, QtCore.SIGNAL(("clicked()")), self.Confirmed)
def Confirmed(self):
self.confirmed = True
MessageBox.close(self)
return True
def Declined(self):
self.declined = True
MessageBox.close(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
msg = MessageBox()
print('Befor show window',msg.confirmed)
msg.show()
print('After show window', msg.confirmed)
sys.exit(app.exec_())
Your example doesn't work, because you are printing "After show window" before the window has closed. It is the exec() method that blocks, not the show() method, so your example would need to be written like this:
app = QtGui.QApplication(sys.argv)
msg = MessageBox()
print('Before show window', msg.confirmed)
msg.show()
app.exec_() # this blocks, waiting for close
print('After show window', msg.confirmed)
sys.exit()
However, a much more realistic example showing how to use a dialog to confirm an action would be something like this:
import sys
from PyQt4 import QtCore, QtGui
class MessageBox(QtGui.QDialog):
def __init__(self, parent=None):
super(MessageBox, self).__init__(parent)
self.yesButton = QtGui.QPushButton('Yes')
self.noButton = QtGui.QPushButton('No')
layout = QtGui.QGridLayout(self)
layout.addWidget(QtGui.QLabel('Are you sure?'), 0, 0)
layout.addWidget(self.yesButton, 1, 0)
layout.addWidget(self.noButton, 1, 1)
self.yesButton.clicked.connect(self.accept)
self.noButton.clicked.connect(self.reject)
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.button = QtGui.QPushButton('Do Something')
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
if self.confirmSomething():
print('Yes')
else:
print('No')
def confirmSomething(self):
msg = MessageBox(self)
result = msg.exec_() == QtGui.QDialog.Accepted
msg.deleteLater()
return result
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
app.exec_()

Call a function from another class by clicking a button PyQt4

I have a checkbox and a run button. When the checkbox is checked, I want to run some functions by clicking the button. The problem is that the function is in another class outside the button's class. My example codes are as below.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Tab1Widget1(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.Tab1Widget1initUI()
def Tab1Widget1initUI(self):
self.setLayout(QGridLayout())
self.T1W1checkBox1 = QCheckBox('a', self)
self.layout().addWidget(self.T1W1checkBox1, 1, 0)
def run(self):
if self.T1W1checkBox1.isChecked() == True:
pass
class Tab1Layout(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QGridLayout())
self.group1 = Tab1Widget1(self)
self.layout().addWidget(self.group1, 0, 0)
btn = QPushButton('Run', self)
self.layout().addWidget(btn, 1, 0)
btn.clicked.connect(Tab1Widget1().run()) ##the problem is in this line.
class Page1(QTabWidget):
def __init__(self, parent=None):
super(Page1, self).__init__(parent)
self.tab1 = Tab1Layout()
self.addTab(self.tab1, "Tab1")
self.tab2 = QWidget()
self.tab3 = QWidget()
self.addTab(self.tab2, "Tab2")
self.addTab(self.tab3, "Tab3")
self.tab2_initUI()
self.tab3_initUI()
def tab2_initUI(self):
grid = QGridLayout()
self.tab2.setLayout(grid)
def tab3_initUI(self):
grid = QGridLayout()
self.tab3.setLayout(grid)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setGeometry(300, 200, 600, 370)
self.startPage1()
def startPage1(self):
x = Page1(self)
self.setWindowTitle("Auto Benchmark")
self.setCentralWidget(x)
self.show()
def main():
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
As you can see, I want to run the "run" function in "Tab1Widget1" class. However, the button is in "Tab1Layout" class.
When I run the codes, it returns to me "TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'"
If anyone knows how to solve this, pls let me know. Appreciated!
There is no problem in connecting any callable to a button click regardless of what object it is in. But your code has two specific problems. You write
btn.clicked.connect(Tab1Widget1().run())
The first problem here is that Tab1Widget1() is creating a new Tab1Widget1 but presumably you don't want that. You want to call run on the Tab1Widget1 you have already created and stored in self.group.
The second problem is that when you connect a signal you need to connect it to a callable: the method you want to call. Instead here you are calling the run method at connect time and trying to connect to the result of that call (which is None). So you are trying to connect the signal to None which will of course fail. You need to refer to the method without calling it: just remove the calling brackets.
Putting it together:
btn.clicked.connect(self.group1.run)
That seems to work.

Categories