This question already has answers here:
How to capture button click from customized QMessageBox?
(3 answers)
Closed 2 years ago.
I want to call "removeDuplicate" method when 'Ok' button on QMessageBox is clicked. But when I click the button the method doesn't execute. What should I do?
Here is my code snippet :
def removeDuplicate(self):
curItem = self.listWidget_2.currentItem()
self.listWidget_2.takeItem(curItem)
def error_popup(self):
msg=QtWidgets.QMessageBox()
msg.setText("You can't select more than one wicket-keeper.")
msg.setWindowTitle(" ")
msg.setIcon(QtWidgets.QMessageBox.Critical)
x = msg.exec_()
msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
msg.buttonClicked.connect(self.removeDuplicate)
Try it:
import sys
from PyQt5.Qt import *
from PyQt5 import QtGui, QtCore, QtWidgets
class Window(QWidget):
def __init__(self):
super().__init__()
self.error_popup()
def removeDuplicate(self):
print('def removeDuplicate(self): ...')
# curItem = self.listWidget_2.currentItem()
# self.listWidget_2.takeItem(curItem)
def error_popup(self):
msg = QMessageBox.critical(
self,
'Title',
"You can't select more than one wicket-keeper",
QMessageBox.Yes | QMessageBox.Cancel
)
if msg == QMessageBox.Yes:
# msg.buttonClicked.connect(self.removeDuplicate)
print('Ok')
self.removeDuplicate()
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(App.exec_())
Related
This question already has answers here:
Argument 1 has unexpected type 'NoneType'?
(2 answers)
Closed 1 year ago.
I am trying to use function when I clicked the button with below source codes:
from PySide2.QtWidgets import QApplication
from ui_interface import *
from Custom_Widgets.Widgets import *
from PyQt5.QtGui import QIcon
# from PyQt5.QtWidgets import *
from Custom_Widgets.Widgets import QCustomSlideMenu
import sys
class MainWindow(QMainWindow):
def __init__(self,parent = None):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
########################################################################
# APPLY JSON STYLESHEET
########################################################################
# self = QMainWindow class
# self.ui = Ui_MainWindow / user interface class
loadJsonStyle(self, self.ui)
########################################################################
self.show()
self.ui.pushButton_2.clicked.connect(self.my_text())
#pyqtSlot()
def on_button1(self):
print("Button #1")
def my_text(self):
index = 1
print("{0} button clicked".format(index))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
# app.setWindowIcon(QIcon(':/icons/home.ico'))
window.show()
sys.exit(app.exec_())
When I using like this:
self.ui.pushButton_2.clicked.connect(self.my_text())
When I clicked the button, does not show anything.
But if I use like this:
self.ui.pushButton_2.clicked.connect(lambda: self.my_text())
It works.
And Also when I use like this:
self.ui.pushButton_2.clicked.connect(self.on_button1())
it works.
But I dont understand why the first step does not working?
try this
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
# setting title
self.setWindowTitle("Python ")
# setting geometry
self.setGeometry(100, 100, 600, 400)
# calling method
self.UiComponents()
# showing all the widgets
self.show()
# method for widgets
def UiComponents(self):
# creating a push button
button = QPushButton("CLICK", self)
# setting geometry of button
button.setGeometry(200, 150, 100, 30)
# adding action to a button
button.clicked.connect(self.clickme)
# action method
def clickme(self):
print("pressed")
# create pyqt5 app
App = QApplication(sys.argv)
# create the instance of our Window
window = Window()
# start the app
sys.exit(App.exec())
is you're looking for this???
If I click Back from the second window, the program will just exit. How do I go back to mainwindow in this case? I assume I will need some more code in that clickMethodBack function.
import os
import PyQt5
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QPushButton
import time
from PyQt5.QtCore import QSize
class GUI_Window():
def __init__(self):
self.main_window()
return
def main_window(self):
app = PyQt5.QtWidgets.QApplication(sys.argv)
self.MainWindow = MainWindow_()
self.MainWindow.show()
app.exec_()
return
class MainWindow_(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.TestAButton = QPushButton("TestA", self)
self.TestAButton.clicked.connect(self.TestA_clickMethod)
self.TestAButton.move(20, 0)
self.CloseButton = QPushButton("Close", self)
self.CloseButton.clicked.connect(self.Close_clickMethod)
self.CloseButton.move(20, 40)
self.TestingA = TestA_MainWindow()
def TestA_clickMethod(self):
self.TestAButton.setEnabled(False)
time.sleep(0.2)
self.TestingA.show()
self.hide()
try:
if self.TestingA.back == True:
self.show()
except:
None
def Close_clickMethod(self):
self.Test_Choice = 'Exit'
self.close()
class TestA_MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setMinimumSize(QSize(980,700))
self.setWindowTitle("TestA")
self.Back_Button = False
self.closeButton = QPushButton("Close", self)
self.closeButton.clicked.connect(self.clickMethodClose)
self.returnButton = QPushButton("Back", self)
self.returnButton.clicked.connect(self.clickMethodBack)
self.returnButton.move(0,30)
def clickMethodClose(self):
self.Back_Button = False
self.close()
def clickMethodBack(self):
self.returnButton.setEnabled(False)
time.sleep(0.5)
self.back = True
self.close()
# Run if Script
if __name__ == "__main__":
main = GUI_Window() # Initialize GUI
Your code has two very important issues.
you're using a blocking function, time.sleep; Qt, as almost any UI toolkit, is event driven, which means that it has to be able to constantly receive and handle events (coming from the system or after user interaction): when something blocks the event queue, it completely freezes the whole program until that block releases control;
you're checking for the variable too soon: even assuming the sleep would work, you cannot know if the window is closed after that sleep timer has ended;
The solution is to use signals and slots. Since you need to know when the second window has been closed using the "back" button, create a custom signal for the second window that will be emitted whenever the function that is called by the button is closed.
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(central)
self.testButton = QtWidgets.QPushButton('Test A')
self.closeButton = QtWidgets.QPushButton('Close')
layout.addWidget(self.testButton)
layout.addWidget(self.closeButton)
self.setCentralWidget(central)
self.testButton.clicked.connect(self.launchWindow)
self.closeButton.clicked.connect(self.close)
def launchWindow(self):
self.test = TestA_MainWindow()
self.test.backSignal.connect(self.show)
self.hide()
self.test.show()
class TestA_MainWindow(QtWidgets.QWidget):
backSignal = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
layout = QtWidgets.QHBoxLayout(self)
self.closeButton = QtWidgets.QPushButton('Close')
self.backButton = QtWidgets.QPushButton('Back')
layout.addWidget(self.closeButton)
layout.addWidget(self.backButton)
self.closeButton.clicked.connect(self.close)
self.backButton.clicked.connect(self.goBack)
def goBack(self):
self.close()
self.backSignal.emit()
def GUI_Window():
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
if __name__ == '__main__':
GUI_Window()
Notes:
I removed the GUI_Window class and made a function, as using a class for that is not really useful;
you should always prefer layout managers instead of setting manual geometries;
widgets should not be added to a QMainWindow as direct children, and a central widget should always be used (see the creation and use of central in the example); read more about it in the documentation;
only classes and constants should be capitalized, while variables, attributes and functions should always have names starting with a lowercase letter;
I want to create a QApplication which is then exited using a keyboard shortcut. Then the python script should call another QApplication.
My issues currently is that I get this error when the second QApplication is about to run:
app2 = QApplication()
RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance.
I have the following structure:
| main.py
| Q1.py
| Q2.py
This is main.py:
import Q1 as record
import Q2 as display
def main():
record.main()
display.main()
if __name__ == "__main__":
main()
This is Q1 which creates the problem:
import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtGui as qtg
from PySide2 import QtCore as qtc
from PySide2 import QtMultimedia as qtmm
class MainWindow(qtw.QMainWindow):
def __init__(self):
super().__init__()
#Create Window layout with a sound widget
soundboard = qtw.QWidget()
soundboard.setLayout(qtw.QGridLayout())
self.setCentralWidget(soundboard)
sw = SoundWidget()
soundboard.layout().addWidget(sw)
#Window Dimensions
self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.MinimumExpanding)
# Code ends here
self.show()
class SendOrderButton(qtw.QPushButton):
button_stylesheet = 'background-color: blue; color: white;'
def __init__(self):
super().__init__('Send Order')
self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Expanding)
self.setStyleSheet(self.button_stylesheet)
#self.clicked.connect(qtc.QCoreApplication.instance().quit)
def press_button(self):
if self.isEnabled():
self.setEnabled(False)
self.setText('Send Order')
else:
self.setEnabled(True)
self.setText('Sent')
class SoundWidget(qtw.QWidget):
def __init__(self):
super().__init__()
self.setLayout(qtw.QGridLayout())
#Send Order Button
self.sendorder_button = SendOrderButton()
self.sendorder_button.setShortcut(qtg.QKeySequence('Tab'))
self.layout().addWidget(self.sendorder_button, 5, 0, 1, 2)
self.sendorder_button.clicked.connect(qtc.QCoreApplication.instance().quit)
def main():
app = qtw.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
This is Q2.py which has the second QApplication:
import sys
from PySide2.QtCore import (QAbstractTableModel, Slot)
from PySide2.QtWidgets import (QAction, QApplication, QMainWindow,QWidget)
class MainWindow(QMainWindow):
def __init__(self, widget):
QMainWindow.__init__(self)
# Exit QAction
exit_action = QAction("Exit", self)
exit_action.setShortcut("Ctrl+Q")
exit_action.triggered.connect(self.exit_app)
#Slot()
def exit_app(self, checked):
sys.exit()
class CustomTableModel(QAbstractTableModel):
def __init__(self, data=None):
QAbstractTableModel.__init__(self)
class Widget(QWidget):
def __init__(self):
QWidget.__init__(self)
# Getting the Model
self.model = CustomTableModel()
def main():
app2 = QApplication()
widget = Widget()
window2 = MainWindow(widget)
window2.show()
sys.exit(app2.exec_())
if __name__ == "__main__":
app = QApplication()
widget = Widget()
window = MainWindow(widget)
window.show()
sys.exit(app.exec_())
As noted in the comments a Qt application can only and should have a QApplication (you might not follow this rule but nothing guarantees that it works correctly) so you will have to restructure your code.
Assuming that you want the Q1 window to be first and when that window is closed then the Q2 window opens that does not imply at any time that you have to use several QApplication. The idea is to know when a window is closed and to be notified of it, to know when a window is closed then you must override the closeEvent method of the window and to make the notification you must send a signal.
Considering the above, the solution is:
├── main.py
├── Q1.py
└── Q2.py
main.py
import sys
from PySide2 import QtWidgets as qtw
import Q1 as record
import Q2 as display
def main():
app = qtw.QApplication(sys.argv)
w1 = record.get_mainwindow()
w2 = display.get_mainwindow()
w1.closed.connect(w2.show)
w1.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Q1.py
from PySide2 import QtWidgets as qtw
from PySide2 import QtGui as qtg
from PySide2 import QtCore as qtc
class MainWindow(qtw.QMainWindow):
closed = qtc.Signal()
def __init__(self):
super().__init__()
# Create Window layout with a sound widget
soundboard = qtw.QWidget()
soundboard.setLayout(qtw.QGridLayout())
self.setCentralWidget(soundboard)
sw = SoundWidget()
soundboard.layout().addWidget(sw)
# Window Dimensions
self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.MinimumExpanding)
sw.sendorder_button.clicked.connect(self.close)
def closeEvent(self, event):
self.closed.emit()
super().closeEvent(event)
class SendOrderButton(qtw.QPushButton):
button_stylesheet = "background-color: blue; color: white;"
def __init__(self):
super().__init__("Send Order")
self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Expanding)
self.setStyleSheet(self.button_stylesheet)
def press_button(self):
if self.isEnabled():
self.setEnabled(False)
self.setText("Send Order")
else:
self.setEnabled(True)
self.setText("Sent")
class SoundWidget(qtw.QWidget):
def __init__(self):
super().__init__()
self.setLayout(qtw.QGridLayout())
# Send Order Button
self.sendorder_button = SendOrderButton()
self.sendorder_button.setShortcut(qtg.QKeySequence("Tab"))
self.layout().addWidget(self.sendorder_button, 5, 0, 1, 2)
def get_mainwindow():
window = MainWindow()
return window
if __name__ == "__main__":
import sys
app = qtw.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Q2.py
from PySide2 import QtCore as qtc
from PySide2 import QtWidgets as qtw
class MainWindow(qtw.QMainWindow):
def __init__(self, widget):
super().__init__()
file_menu = self.menuBar().addMenu("&File")
# Exit QAction
exit_action = qtw.QAction("Exit", self)
exit_action.setShortcut("Ctrl+Q")
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
class CustomTableModel(qtc.QAbstractTableModel):
pass
class Widget(qtw.QWidget):
def __init__(self):
super().__init__()
# Getting the Model
self.model = CustomTableModel()
def get_mainwindow():
widget = Widget()
window2 = MainWindow(widget)
return window2
if __name__ == "__main__":
import sys
app = qtw.QApplication()
widget = Widget()
window = MainWindow(widget)
window.show()
sys.exit(app.exec_())
This question already has answers here:
Aligning text in QTextEdit?
(2 answers)
Closed 4 years ago.
I am doing some random choice picker where there's a place to display info user keyed in. (which I used text browser), How do I set the text to be always align center?
self.textBrowser.setText(newList + "\n\nanalyzing in ...")
QtTest.QTest.qWait(1000)
self.textBrowser.setText(newList + "\n\nanalyzing in ..." + "\n\n 3")
QTextBrowser Class Inherits: QTextEdit
QTextEdit::setAlignment(Qt::Alignment)
Sets the alignment of the current paragraph to a. Valid alignments are Qt::AlignLeft, Qt::AlignRight, Qt::AlignJustify and Qt::AlignCenter (which centers horizontally).
Sorry, I have PyQt5:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Win(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.i = 5
self.textBrowser = QtWidgets.QTextBrowser()
self.textBrowser.setAlignment(QtCore.Qt.AlignCenter) # <-------------
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.textBrowser)
self.setLayout(layout)
timer = QtCore.QTimer(self, interval=1000, timeout=self.print_out)
timer.start()
def print_out(self, string="Hello world!"):
self.textBrowser.append(string + "\n\nanalyzing in ...\n {}".format('----' * self.i))
self.i += 1
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
myWin = Win()
myWin.show()
sys.exit(app.exec_())
I have used QT Designer to have two QLineEdit's to take input from the user. After the user enters the values , when the Enter button is clicked I need the buttons to pass the values to the disk_angles function.
How to pass two strings to a function via signals with the press of a button?
Here is my code
class Maindialog(QMainWindow,diskgui.Ui_MainWindow):
pass_arguments = SIGNAL((str,),(str,))
def __init__(self,parent = None):
super(Maindialog,self).__init__(parent)
self.setupUi(self)
self.connect(self.Home,SIGNAL("clicked()"),self.home_commands)
self.connect(self.AutoFocus,SIGNAL("clicked()"),self.auto_focus)
self.Enter.clicked.connect(self.entervalues)
self.connect(self,SIGNAL("pass arguments"),self.Criterion_disk_angles)
def entervalues(self):
if self.RotationEdit.text() != "" and self.TiltEdit.text() != "":
self.RotationEdit = str(self.RotationEdit.text())
self.TiltEdit = str(self.TiltEdit.text())
self.pass_arguments.emit(self.RotationEdit,self.TiltEdit)
def disk_angles(self,rotation_angle, tilt_angle):
I have tried to pass tuples as input to the signal
pass_arguments = SIGNAL((str,),(str,))
but I get the error
pass_arguments = SIGNAL((str,),(str,))
TypeError: SIGNAL() takes exactly one argument (2 given)
In PyQt5 it is recommended to use the new style, In addition you are sending 2 tuples of place of one, here I show an example of a correct implementation.
import sys
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QPushButton
class Widget(QObject):
sig = pyqtSignal((str, str))
def __init__(self, parent=None):
super(Widget, self).__init__(parent=parent)
self.sig.connect(self.printer)
def click(self):
self.sig.emit("hello", "bye")
def printer(self, text1, text2):
print(text1, text2)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QPushButton()
w1 = Widget()
w.clicked.connect(w1.click)
w.show()
sys.exit(app.exec_())