GUI 的两种不同语法 -> 不同的行为
Two different syntax for the GUI -> Different behaviours
我正在研究 PyQt,有些事情对我来说绝对不清楚。
假设我想创建一个带有按钮的 GUI。
网上很多例子都是这种形式:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 200, 140)
self.setWindowTitle('Dialog')
self.aaa = QtWidgets.QPushButton(self)
self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
self.aaa.setObjectName("aaa")
self.aaa.setText( "PushButton")
self.show()
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
但是,如果我使用 Designer 创建相同的 GUI,然后通过 'pyuic5 -x test.ui -o test.py' 将其转换为 Python,我会得到一个稍微不同的代码:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setGeometry(300, 300, 200, 140)
self.aaa = QtWidgets.QPushButton(Dialog)
self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
self.aaa.setObjectName("aaa")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.aaa.setText(_translate("Dialog", "PushButton"))
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
除调用等不同外:
self.setGeometry(300, 300, 200, 140)
而不是
Dialog.setGeometry(300, 300, 200, 140)
有些差异我无法理解。
- keyPressEvent 在第一个示例中有效,在第二个示例中无效
- 如果我在第一个例子中按下 'Escape' 什么都不会发生,如果我在第二个例子中按下它应用程序会立即关闭
- 按钮在第二个例子中突出显示(因为它被设置为默认,我找到了禁用它的方法)而在第一个例子中没有
我正在寻找解释这一点的 guides 和教程,但我只能找到第一种语法的示例,而第二种语法对我来说更好,因为我可以使用 Designer 设计 GUI然后将其导出到 python 以添加事件。
那么我的实际问题是:
- 如何避免在第二个示例中使用退出按钮来 quit 我的应用程序?
- 如何让 keyPressEvent 在第二个示例中工作?
一般情况下更多:
- 我应该更喜欢第一种语法还是第二种语法,或者它们是 equivalent?
- 有没有办法将设计器文件“.ui”导出到具有第一个示例语法的 python 文件?
谢谢!
如何避免在第二个示例中使用退出按钮退出我的应用程序?
此按钮默认激活,因为在第二个示例中您使用的 QDialog
小部件具有此默认行为,因为它们用于创建用户必须 select 选项的对话框,相反,第一个示例使用的是最基本的小部件 QWidget
。
解决方案:将 Widget 用作模板,而不是一些没有按钮的对话框、底部有按钮的对话框或右侧有按钮的对话框。
如何让 keyPressEvent 在第二个示例中工作?
Qt Designer创建设计class,不创建widget,即class创建填充widget,在第一段代码的main中观察到,只有widget有事件键按下事件。解决方法很简单,你必须创建一个继承自Dialog的class,并用Qt Designer提供的class实现widget的填充。
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setupUi(self)
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
注:
以下架构显示了您在 Qt 设计器中使用的模板以及您必须继承的 classes:
+-----------------------------+--------------+
| Template | Widget Class |
+-----------------------------+--------------+
| Dialog with Buttons Bottom | QDialog |
| Dialog with Buttons Right | QDialog |
| Dialog without Buttons | QDialog |
| MainWindow | QMainWindow |
| Widget | QWidget |
+-----------------------------+--------------+
一般来说你必须使用以下方案:
class Some_Name(Widget_Class, Template):
def __init__(self, *args, **kwargs):
Widget_Class.__init__(self, *args, **kwargs)
self.setupUi(self)
有关更多信息,请查看以下内容:
我正在研究 PyQt,有些事情对我来说绝对不清楚。 假设我想创建一个带有按钮的 GUI。 网上很多例子都是这种形式:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 200, 140)
self.setWindowTitle('Dialog')
self.aaa = QtWidgets.QPushButton(self)
self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
self.aaa.setObjectName("aaa")
self.aaa.setText( "PushButton")
self.show()
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
但是,如果我使用 Designer 创建相同的 GUI,然后通过 'pyuic5 -x test.ui -o test.py' 将其转换为 Python,我会得到一个稍微不同的代码:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setGeometry(300, 300, 200, 140)
self.aaa = QtWidgets.QPushButton(Dialog)
self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
self.aaa.setObjectName("aaa")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.aaa.setText(_translate("Dialog", "PushButton"))
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
除调用等不同外:
self.setGeometry(300, 300, 200, 140)
而不是
Dialog.setGeometry(300, 300, 200, 140)
有些差异我无法理解。
- keyPressEvent 在第一个示例中有效,在第二个示例中无效
- 如果我在第一个例子中按下 'Escape' 什么都不会发生,如果我在第二个例子中按下它应用程序会立即关闭
- 按钮在第二个例子中突出显示(因为它被设置为默认,我找到了禁用它的方法)而在第一个例子中没有
我正在寻找解释这一点的 guides 和教程,但我只能找到第一种语法的示例,而第二种语法对我来说更好,因为我可以使用 Designer 设计 GUI然后将其导出到 python 以添加事件。 那么我的实际问题是:
- 如何避免在第二个示例中使用退出按钮来 quit 我的应用程序?
- 如何让 keyPressEvent 在第二个示例中工作?
一般情况下更多:
- 我应该更喜欢第一种语法还是第二种语法,或者它们是 equivalent?
- 有没有办法将设计器文件“.ui”导出到具有第一个示例语法的 python 文件?
谢谢!
如何避免在第二个示例中使用退出按钮退出我的应用程序?
此按钮默认激活,因为在第二个示例中您使用的 QDialog
小部件具有此默认行为,因为它们用于创建用户必须 select 选项的对话框,相反,第一个示例使用的是最基本的小部件 QWidget
。
解决方案:将 Widget 用作模板,而不是一些没有按钮的对话框、底部有按钮的对话框或右侧有按钮的对话框。
如何让 keyPressEvent 在第二个示例中工作?
Qt Designer创建设计class,不创建widget,即class创建填充widget,在第一段代码的main中观察到,只有widget有事件键按下事件。解决方法很简单,你必须创建一个继承自Dialog的class,并用Qt Designer提供的class实现widget的填充。
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setupUi(self)
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Return:
self.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
注:
以下架构显示了您在 Qt 设计器中使用的模板以及您必须继承的 classes:
+-----------------------------+--------------+
| Template | Widget Class |
+-----------------------------+--------------+
| Dialog with Buttons Bottom | QDialog |
| Dialog with Buttons Right | QDialog |
| Dialog without Buttons | QDialog |
| MainWindow | QMainWindow |
| Widget | QWidget |
+-----------------------------+--------------+
一般来说你必须使用以下方案:
class Some_Name(Widget_Class, Template):
def __init__(self, *args, **kwargs):
Widget_Class.__init__(self, *args, **kwargs)
self.setupUi(self)
有关更多信息,请查看以下内容: