PyQt5 Display QMessageBox and QInputDialog immediately
我很好奇为什么QInputDialog和QMessageBox.question总是立即显示?对于其他PyQT元素,需要显示UI内容的初始序列。
1 2 3 4 5 6 7 8 9 10 | # Example of a Basic PyQT5 UI Application app = QApplication(sys.argv) w = QWidget() w.resize(250, 150) w.move(300, 300) w.setWindowTitle('Simple') w.show() sys.exit(app.exec_()) |
我一直在寻找适当的文档,但没有发现任何突出的内容。因此,我希望有人可以指出如何修改窗口小部件类或在哪里可以找到适当的文档。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QLabel, QMessageBox, QHBoxLayout, QInputDialog from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QIcon, QPixmap class QuestionPopup(QWidget): def __init__(self, question = None): super().__init__() self.title = 'Question Popup' self.left = 250 self.top = 50 self.width = 320 self.height = 200 self.question = question self._response = None self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) buttonReply = QMessageBox.question(self, 'PyQt5 message', self.question, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: self.response = True else: self.response = False self.show() def getText(self): text, okPressed = QInputDialog.getText(self,"Get text","Your name:", QLineEdit.Normal,"") if okPressed and text != '': print(text) |
我的目标是创建将显示图像并要求用户输入有关图像的自定义对话框。我的代码非常复杂,不能仅仅显示一个新的UI窗口。我需要允许QMessageBox和QInputDialog都立即显示的功能。
正如@TheKewlStore所说,您引用的方法是静态的,并且在可以修改的内容方面受到限制。它们包含使它们立即显示而不是要求使用
首先创建一个简单的消息框,然后关闭它,将创建并显示一个基本对话框,该对话框可以显示图像,用于指示用户的一行文本,用于输入文本的位置,以及"确定"和"取消"按钮-我只连接了"确定"按钮以简单地打印用户的输入。显然,您可以插入按钮所需的任何命令以及用户输入会发生什么。我还使用了一些网格布局,主要是因为我喜欢它使内容保持整洁的方式,但并不是强制执行此工作的方法。也可以使盒子的尺寸更加动态,我只是觉得这里不需要它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | import sys from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit from PyQt5.QtGui import QIcon from PyQt5 import QtWidgets, QtCore import PyQt5 import os class MsgBox(object): def setupUi(self, show_msgbox): show_msgbox.setObjectName("show_msgbox") show_msgbox.setText('Show your message text here') class MsgPrompt(PyQt5.QtWidgets.QMessageBox, MsgBox): app = PyQt5.QtWidgets.QApplication(sys.argv) def __init__(self): super(MsgPrompt, self).__init__() self.setupUi(self) super(MsgPrompt, self).exec_() class UserInput(object): def setupUi(self, get_user_input): # Basic shape self.width = 425 get_user_input.setObjectName("get_user_input") get_user_input.resize(425, self.width) self.frame = QtWidgets.QFrame(get_user_input) self.frame.setGeometry(QtCore.QRect(11, 10, 401, 381)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Sunken) self.frame.setObjectName("frame") # Creating the grid layout for most of the display elements self.gridLayoutWidget = QtWidgets.QWidget(self.frame) self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 381, 361)) self.gridLayoutWidget.setObjectName("gridLayoutWidget") self.get_user_input_layout = QtWidgets.QGridLayout(self.gridLayoutWidget) self.get_user_input_layout.setContentsMargins(5, 5, 5, 5) self.get_user_input_layout.setObjectName("get_user_input_layout") # Grid layout for the buttons self.buttonLayoutGrid = QtWidgets.QWidget(get_user_input) self.buttonLayoutGrid.setGeometry(QtCore.QRect(10, 390, 401, 41)) self.buttonLayoutGrid.setObjectName("buttonLayoutGrid") self.buttonLayout = QtWidgets.QGridLayout(self.buttonLayoutGrid) self.buttonLayout.setContentsMargins(0, 0, 0, 0) self.buttonLayout.setObjectName("buttonLayout") # Adding buttons self.buttonOK = QtWidgets.QPushButton(self.buttonLayoutGrid) self.buttonOK.setObjectName("buttonOK") self.buttonOK.setText("OK") self.buttonLayout.addWidget(self.buttonOK, 0, 1, 1, 1) self.buttonCancel = QtWidgets.QPushButton(self.buttonLayoutGrid) self.buttonCancel.setObjectName("buttonCancel") self.buttonCancel.setText("CANCEL") self.buttonLayout.addWidget(self.buttonCancel, 0, 2, 1, 1) # Adding the place for the image self.image = QtWidgets.QLabel(self.gridLayoutWidget) self.get_user_input_layout.addWidget(self.image, 0, 0, 1, 1) # Add instructions for the user self.user_prompt_text = QtWidgets.QLabel(self.gridLayoutWidget) self.user_prompt_text.setText('WHAT IS THIS PIC?') self.user_prompt_text.setAlignment(PyQt5.QtCore.Qt.AlignLeft) self.get_user_input_layout.addWidget(self.user_prompt_text, 1, 0, 1, 1) # Add a field for the user to enter text self.user_input_box = PyQt5.QtWidgets.QLineEdit(self.gridLayoutWidget) self.user_input_box.setObjectName('user_input_box') self.user_input_box.setEnabled(True) self.get_user_input_layout.addWidget(self.user_input_box, 2, 0, 1, 1) # This is an optional call QtCore.QMetaObject.connectSlotsByName(get_user_input) class UserInputPrompt(PyQt5.QtWidgets.QDialog, UserInput): app = PyQt5.QtWidgets.QApplication(sys.argv) def __init__(self, path_to_image): super(UserInputPrompt, self).__init__() self.setupUi(self) self.path_to_image = path_to_image self.user_input_box.setFocus() self.buttonOK.clicked.connect(self.get_user_input) self.image.setPixmap(PyQt5.QtGui.QPixmap(self.path_to_image).scaledToWidth(self.width self.image.show() super(UserInputPrompt, self).exec_() def get_user_input(self): print(self.user_input_box.text()) MsgPrompt() UserInputPrompt('your_image_file.jpg') |
您的问题中引用的方法是QInputDialog和QMessageBox的静态成员,它们是同步的阻塞调用。这是通过模拟而不是调用show,而是在对话框上调用exec来模拟的。 exec与show相似(在pyqt中,exec是exec_以避免与python内置exec发生冲突),但是它实际上会阻塞所有其他UI组件,直到它提供控制为止(从技术上讲,这是通过暂停主事件循环并运行它来实现的)特定于对话框,最终放弃控制权)。在此处查看有关此内容的更多信息:https://doc.qt.io/qt-5/qmessagebox.html#exec
请注意,这是特定于上述静态函数的行为。您可以在不使用这些功能的情况下创建自己的QMessageBox,它会以正常方式运行,即直到您显式调用show才会显示。
这里是一个示例函数,它显示了如何在后台实现QMessageBox.static的高级细节(尽管这不是实际的代码):
1 2 3 | def question(parent, title, message, buttons): message_box = QMessageBox(question_icon, title, message, buttons) return message_box.exec_() |
要点是要获得那些静态函数正在使用的行为,您需要在对话框上调用exec_而不显示。请注意,exec_仅在特定的窗口小部件类型上可用,最值得注意的是从QDialog继承的任何东西。您还应该注意exec是一个同步的阻塞调用这一事实,这意味着在处理该对话框之前,不会在应用程序的主线程上运行任何其他操作。