繁体   English   中英

PyQt5 很简单的按钮输入对话框

[英]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)
  1. 我使用了一个全局变量,因为我没有找到从 QApplication 返回任何东西的方法。

  2. 无论我按哪个键,output 都是“开发”,最后输入的那个选项?

主要问题在 lambda scope 中:lambda 中的内容lambda:仅在执行时才进行评估。
单击按钮时, for循环已经完成,此时option将是循环中分配的最后一个值。

解决方案是“强制”关键字 arguments,以便在内部 scope 中有一个持久引用。注意 Qt 按钮的clicked信号有一个checked参数,你必须考虑在 lambda 位置 arguments。

然后,而不是创建一个全局变量(这几乎总是一个糟糕的选择),你应该正确地使用 QDialog 的功能:

  1. 使用exec() ,它会阻止执行(但不会阻止事件循环),直到对话框返回;
  2. 使用done()为对话框设置有效结果并通过返回该结果关闭它;
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())

进一步说明:

  • 总是使用布局管理器,创建子部件是不够的,尝试设置手动几何仍然是不够的,除非你对 Qt 事件、尺寸提示和策略有深入的了解和深刻的经验;
  • 不要不必要地调用del (在这种情况下,它也完全没有意义,因为它只会删除 python 引用,并且它是一个局部变量,会在每个 for 循环和__init__返回时收集垃圾,它是无用的);
  • 尽可能避免使用局部函数,而总是更喜欢实例方法;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM