【问题标题】:Control not returning after self.close() encountered in PyQt在 PyQt 中遇到 self.close() 后控件不返回
【发布时间】:2014-10-31 05:35:53
【问题描述】:

我正在尝试使用 PyQt 制作 UI。它有一个非常基本的工作。当脚本在终端上运行时,按下 Ok 时会打开和关闭询问名称的对话框。但是,我无法从 Qt 应用返回控件。

我的代码如下:

class Interactive(QtGui.QWidget):

    def __init__(self):
        super(Interactive,self).__init__()
        self.initGUI()

    def initGUI(self):
            self.setGeometry(300,300,290,150)
            self.setWindowTitle('Input Dialog')
            self.show()

            self.inputdialog =  QtGui.QInputDialog()
            self.inputdialog.move(50,50)

            text, ok = self.inputdialog.getText(self,'Input Dialog','Enter Your Name:')
            #self.text = text
            if ok:
                self.text = text    
                print text
                self.close()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    obj = Interactive()
    #app.exec_()
    if app.exec_():
        sys.exit()
        print "somerandomtext"

类中的print text 可以正常工作,但我的测试字符串"somerandomtext" 不能正常工作,并且程序没有结束。

我在 So 中查看了类似的问题,但似乎没有一个解决相同的问题。我必须为此创建另一个处理程序吗?

【问题讨论】:

  • 因为您在打印之前使用的是 sys.exit() 。所以它永远不会在退出后打印任何东西。
  • 如果 sys.exit() 已经执行,程序就会终止,正如我已经说过的,程序没有终止

标签: python qt pyqt pyqt4


【解决方案1】:

通常情况下,应用程序会在最后一个顶级窗口关闭时自动退出,但在您的示例中不会发生这种情况,因为您不允许事件循环正常启动。

有很多方法可以重新构建您的示例以避免此问题,但可能最简单的方法是使用这样的计时器:

class Interactive(QtGui.QWidget):
    def __init__(self):
        super(Interactive,self).__init__()
        # delay initialization
        # self.initGUI()
        ...

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    obj = Interactive()
    QtCore.QTimer.singleShot(0, obj.initGUI)
    app.exec_()
    print "somerandomtext"

PS

deleteLater() 在另一个答案中起作用的原因是它向事件队列发布了一个删除事件(一旦事件循环正确启动,它将被处理)。 close() 方法不会以这种方式发布事件,因此应用程序没有机会自动退出。

【讨论】:

  • 非常感谢您的回答。你能描述一下“不允许事件循环正常启动”的意思吗?它与 ram 等系统配置有关吗?
  • 不,只是您的initGUI 在事件循环开始之前尝试做太多事情。如果您在打开对话框的主窗口上有一个按钮,它也可以解决问题。这只是在用户开始与 gui 交互之前允许一小段延迟的问题。
  • 好的。但早些时候我尝试了一个没有输入对话框的类似示例,添加了一个按钮并在其事件处理程序中编写了 self.close() 并且它工作正常。那为什么在这里?
  • 启动输入对话框的方式意味着它使用自己的事件循环(在内部,Qt 使用exec() 打开对话框)。这允许您与对话框进行交互,但它也阻止了主应用程序事件循环的启动。主窗口的关闭发生在 对话框退出其事件循环之后,但 之前 主事件循环开始。如果您使用其show() 方法打开对话框,它不会启动自己的事件循环,也不会出现问题。一个小的(异步)延迟也将允许主事件循环在主窗口关闭之前启动。
  • 非常感谢您的解释。
【解决方案2】:
if ok:
                self.text = text    
                print text
                self.deleteLater()

应该终止应用程序

猜你喜欢
  • 1970-01-01
  • 2016-04-07
  • 2020-04-30
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
  • 2016-08-15
  • 2018-08-07
相关资源
最近更新 更多