PySide:当触发另一个QMainWindow(主窗口)中的QAction时,为什么QMainWindow会闪烁并消失。

2024-10-01 22:28:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我是PySide的新手。我遇到了一个问题:当我从另一个QMainWindow(主UI)触发一个QAction时,一个新的QMainWindow闪烁消失了

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
       super(MainWindow, self).__init__(parent)
       ...
       self.execTaskAct = QtGui.QAction("execute", self,  triggered=self.executeTask)
       ...

    def  executeTask(self):
      task = TaskWindow()

class  TaskWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
       super(TaskWindow, self).__init__(parent)
       ...
      self.show()


if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

Tags: selfnoneinitdefshowsysclassparent
2条回答

在创建新QMainWindow之后,您不会保留对它的引用,而且由于新窗口(TaskWindow)没有父窗口,一旦executeTask方法运行,该窗口就会被垃圾回收。在

您只需保留对新窗口的引用,方法是将executeTask更改为:

def  executeTask(self):
    self.task = TaskWindow()

请注意,如果操作运行两次,这将覆盖第一个TaskWindow,并使其消失,或者应用程序崩溃。您可以计算出在这种情况下应该发生什么,或者更好地存储多个TaskWindows的引用(例如在列表中)。在

请注意,只有在QWidgets没有父级的情况下才需要存储它们的引用(在当前的情况下是这样)。如果一个QWidget有一个父级,Qt在内部存储一个引用。在

首先,从外观上看,您的代码包含一个语法错误,这是由于不一致的缩进造成的,这是python中的一个问题。在

更重要的是,在execute方法中创建了一个本地对象,一旦方法完成,本地创建的对象就会被销毁。在

这是因为qwidgets的show()方法没有阻塞。当事件循环可用时,它们将只为Qt事件循环排队以处理请求。在

您可以将变量类的作用域设置为MainWindow,但随后可以将创建TaskWindow的创建移动到init方法,以避免每次发出信号时不必要的对象创建,并且您将只在execute方法中显示TaskWindow,如下所示:

def __init__(self, parent = None):
   super(MainWindow, self).__init__(parent)
   ...
   self.execTaskAct = QtGui.QAction("execute", self,  triggered=self.executeTask)
   ...
   self.task = TaskWindow()

def  executeTask(self):
  task.show()

如果您真的希望每次触发执行时都构造一个新对象,那么您可以在前面加上“self”关键字,使每个新创建的对象类都具有作用域。但是,请确保不要在未定义的行为中留下未引用的窗口。所以,你可以这样写:

^{pr2}$

当然,您需要从TaskWindow的init方法中删除show()调用。在

也就是说,为了完整起见,我还将为TaskWindow分配一个父级,无论是主窗口还是应用程序对象本身。在

self.task = TaskWindow(self)

另外请注意,如果您只想看到一个窗口,您可能希望通过调用主窗口的hide()方法来隐藏主窗口。如果希望同时显示这两个窗口,可以考虑使用TaskDialog而不是两个MainWindow。在

此外,一旦完成执行,如果用户不希望显式关闭TaskWindow,则可能希望显式地hide()。这取决于你的用例。在

相关问题 更多 >

    热门问题