我是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_())
答案 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。这取决于您的使用案例。