PySide:为什么QMainWindow在另一个QmainWIndow(Main)中触发QAction时出现并消失

时间:2014-01-14 02:05:25

标签: python qt pyside qtgui qmainwindow

我是PySide的新手。我遇到一个问题:当我从另一个QmainWIndow(主用户界面)触发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_())

2 个答案:

答案 0 :(得分:2)

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

您只需将executeTask更改为:

即可保留对新窗口的引用
def  executeTask(self):
    self.task = TaskWindow()

请注意,如果操作运行两次,则会覆盖第一个TaskWindow并使其消失,或者您的应用崩溃。您可以弄清楚在这种情况下应该发生什么,或者更好的方法来存储多个TaskWindow的引用(例如在列表中)。

请注意,如果QWidgets没有父级,则只需存储QWidgets的引用(在当前情况下为true)。如果QWidget具有父级,则Qt在内部存储引用。

答案 1 :(得分:0)

首先,由于缩进不一致,你的代码包含了一个语法错误,这是python中的一个问题。

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

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

您可以将变量类作为范围设置为MainWindow,但是您可以将创建TaskWindow创建的init方法移动到每次发出信号时避免不必要的对象创建,并且您只在执行中显示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”关键字来使每个新创建的对象类都作用域。但是,请确保不要在未定义的行为中留下未引用的窗口。所以,你会写这样的东西:

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

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

话虽这么说,我还会将一个父级分配给TaskWindow以获得完整性,即MainWindow或应用程序对象本身。

self.task = TaskWindow(self)

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

此外,一旦完成执行,如果您的用户不应该明确地关闭它,您可能希望显式隐藏()您的TaskWindow。这取决于您的使用案例。