我正在编写一个小型 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/