python - PyQt 相当于 WinForms 激活事件是什么?

标签 python pyqt pyqt5

我正在编写一个小型 PyQt 应用程序,需要在应用程序启动之前运行一些检查,如果任何检查失败,应用程序需要通知用户它无法运行,然后退出。

在 WinForms 中。我可以简单地实现这一点:

var form = new Form();
form.Activated += (s, e) =>
{
    var condition = true;
    if (condition)
    {
        MessageBox.Show("oh dear, something's wrong.");
        Application.Exit();
    }
};

当主应用程序窗口加载时,PyQt 似乎没有可以连接的信号,并且我当前的尝试在条件失败时甚至不会触发对话框。

这就是我现在所拥有的(MRE(。程序流程如下:

import sys
import winreg
from PyQt5.QtWidgets import QApplication, QWidget,  QMessageBox

class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

    def loadData(self):
        try:
            key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Path\To\Nonexistant\Key')
            x = winreg.QueryValueEx(key, 'some_key')[0]
            print(x)
        except FileNotFoundError:
            error = QMessageBox()
            error.setIcon(QMessageBox.Critical)
            error.setText('Cannot locate installation directory.')
            error.setWindowTitle('Cannot find registry key')
            error.setStandardButtons(QMessageBox.Ok)
            error.show()
            QApplication.quit()

def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    main_window.loadData()
    sys.exit(app.exec_())


main()

我的最终目标是能够在应用程序完全加载并向用户显示时让 loadData() 运行。

更新:程序现在按预期运行。我必须:

  • error.show() 更改为 error.exec_()
  • QApplication.quit()更改为sys.exit()
  • main_window.show() 之后调用 main_window.loadData()

最佳答案

show方法不是阻塞的,所以一旦执行,QMessageBox就会在QApplication.quit()处显示,而你应该使用exec_() 将等到用户通过按钮关闭 QMessageBox。

# ...
error.setStandardButtons(QMessageBox.Ok)
# error.show()
<b>error.exec_()</b>
QApplication.quit()
<小时/>

更新:

另一方面,当事件循环尚未启动时,无法使用 QApplication.quit(),因此这种情况下的解决方案是稍后使用 QTimer.singleShot() 删除应用程序:

class MainWindow(QWidget):

    # UI stuff omitted...

    def loadData(self):
        try:
            key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Path\To\Key')
            path = winreg.QueryValueEx(key, 'install_path')[0]
            # I'll do stuff with path here...
        except FileNotFoundError:
            error = QMessageBox()
            error.setIcon(QMessageBox.Critical)
            error.setText('Cannot locate directory.')
            error.setWindowTitle('Cannot find registry key')
            error.setStandardButtons(QMessageBox.Ok)
            <b>error.exec_()
            QTimer.singleShot(0, QApplication.quit)</b>


def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    <b>main_window.loadData()</b>
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

另一个等效代码如下

class MainWindow(QWidget):

    # UI stuff omitted...

    def loadData(self):
        try:
            key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Path\To\Key')
            path = winreg.QueryValueEx(key, 'install_path')[0]
            # I'll do stuff with path here...
        except FileNotFoundError:
            error = QMessageBox()
            error.setIcon(QMessageBox.Critical)
            error.setText('Cannot locate directory.')
            error.setWindowTitle('Cannot find registry key')
            error.setStandardButtons(QMessageBox.Ok)
            <b>error.exec_()</b>
            QApplication.quit()


def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    <b>QTimer.singleShot(0, main_window.loadData)</b>
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

关于python - PyQt 相当于 WinForms 激活事件是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59534796/

相关文章:

python - 如何避免循环导入

python - 如何在 snakemake 管道中使用 pandas

css - QTextBrowser 中的顶部边距不起作用

linux - 在 Linux (Linux mint) 中创建您自己的定制应用程序软件中心的最佳方法是什么?

python - 获取 QTableView 单元格值

Python求和麻烦

python - RNN 单元不存在于 tf.get_collection 中

python - 我怎样才能在 pyside QWidget 中有一个透明的背景,但保持它的 child 不透明

python - 使用 pyinstaller 编译为 .exe 后 PyQt5 应用程序缺少图标

python - 为什么 PlotWidget 在 GridLayout 单元格中无法缩放?