[英]PyQt5 very simple button input dialog
我想我会尝试 pyqt(5) 进行更改,并希望在脚本启动时创建一个简单的对话框,让用户从三个选项中选择一个。
我的目标是像这样的弹出窗口(在脚本启动时),它将在按下其中一个按钮时关闭并返回按下的按钮的值:
这就是我尝试实现它的方式:
from PyQt5.QtWidgets import QApplication, QDialog, QPushButton, QDialogButtonBox
input_db_connection="None"
class MyDialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle("Choose Database connection")
self.buttonBox=QDialogButtonBox(self)
for option in ["Production Read", "Production Read&Write", "Development"]:
b = QPushButton(option)
b.clicked.connect(lambda x: return_and_close(option))
self.buttonBox.addButton(b,0)
del b
def return_and_close(value):
global input_db_connection
print(value)
input_db_connection=value
self.close()
app = QApplication([])
dg = MyDialog()
dg.show()
app.exec()
print(input_db_connection)
我使用了一个全局变量,因为我没有找到从 QApplication 返回任何东西的方法。
无论我按哪个键,output 都是“开发”,最后输入的那个选项?
主要问题在 lambda scope 中:lambda 中的内容lambda:
仅在执行时才进行评估。
单击按钮时, for
循环已经完成,此时option
将是循环中分配的最后一个值。
解决方案是“强制”关键字 arguments,以便在内部 scope 中有一个持久引用。注意 Qt 按钮的clicked
信号有一个checked
参数,你必须考虑在 lambda 位置 arguments。
然后,而不是创建一个全局变量(这几乎总是一个糟糕的选择),你应该正确地使用 QDialog 的功能:
from PyQt5.QtWidgets import *
class MyDialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle("Choose Database connection")
layout = QVBoxLayout(self)
self.buttonBox = QDialogButtonBox(self)
layout.addWidget(self.buttonBox)
states = [
(0, "Production Read"),
(1, "Production Read&Write"),
(2, "Development"),
]
for value, option in states:
b = QPushButton(option)
b.clicked.connect(lambda _, value=value: self.done(value))
self.buttonBox.addButton(b, 0)
app = QApplication([])
dg = MyDialog()
print(dg.exec())
进一步说明:
del
(在这种情况下,它也完全没有意义,因为它只会删除 python 引用,并且它是一个局部变量,会在每个 for 循环和__init__
返回时收集垃圾,它是无用的);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.