Python 延迟检查小部件是否存在

Python 延迟检查小部件是否存在,python,qt,pyqt,Python,Qt,Pyqt,我一直在为Nuke的对接面板工作而头疼。它与QStackedWidgets一起作为选项卡工作,整个程序都是用它构建的,非常动态 记录在案,我一直在处理这样的事情,它是有效的,但需要大量的尝试和错误才能弄清楚: def x(self): return self.parent().parent().parent().parent().parent().parent().parent().x() def y(self): return self.parent().parent().pa

我一直在为Nuke的对接面板工作而头疼。它与
QStackedWidgets
一起作为选项卡工作,整个程序都是用它构建的,非常动态

记录在案,我一直在处理这样的事情,它是有效的,但需要大量的尝试和错误才能弄清楚:

def x(self):
    return self.parent().parent().parent().parent().parent().parent().parent().x()
def y(self):
    return self.parent().parent().parent().parent().parent().parent().parent().y()
def closeEvent(self, event):
    is_docked = self.x() == self.y() == 0
    num_tabs = widget.parent().parent().parent().parent().parent().parent().parent().parent().count()

    #Delete the window
    if not is_docked and num_tabs == 1:
        self.parent().parent().parent().parent().parent().parent().parent().parent().parent().close()

    #Delete the tab
    else:
        for obj in QtWidgets.QApplication.allWidgets():
            if obj.objectName() == 'uk.co.thefoundry.NukeTestWindow':
                 obj.deleteLater()
    event.accept()
我试图获得完全控制权,以便稍后处理回调,这有点困难,因为它从不调用
closeEvent
。我目前可以处理自动关闭它,并且我将使用
hideEvent
读取窗口位置,因为它在关闭之前调用

我已经获得了几乎所有需要的功能,但我仍然无法捕捉到用户手动关闭选项卡的时间。我已经从技术上解决了如何检测它是否关闭的问题,但它只有在函数完成后才能工作

如果我打印出
self.parent().parent().parent().parent().parent().parent().parent().parent()
,它会说这是一个小部件,但如果我在代码执行后打印,那么它就等于
None
,因此这是理想情况下要检查的父级

我如何在
hideEvent
中查询它,但在完成所有操作之前偏移执行?据我所知,之后没有调用其他事件,我考虑过使用
time.sleep
线程,但它不是很干净,很容易出现问题


Maya有一个名为
evalDeferred
的命令,在这种情况下非常有用。我刚刚用NukeScript.utils.ExecuteFerred进行了一次快速测试,但即使睡了一秒钟也不起作用。

可以使用QTimer::singleShot将方法延迟x ms

例如:
QTimer::singleShot(50,this,&MyWidget::mySlot)将在调用此指令50毫秒后执行插槽mySlot。这相当于制作一个QTimer,并将其结束事件与所述插槽连接。
也别忘了,如果你愿意,mySlot可以这样称呼自己

void MyWidget::mySlot() {
     if(conditionOK) {
         // Do stuff
     }
     else {
         // Try again 50ms later
          QTimer::singleShot(50, this, &MyWidget::mySlot) ;
     }
}
小心点,因为你不能保证在这50毫秒内会发生什么。因此,这不是一种“一有结果就执行”的交易。还要注意避免无限递归。 希望能有帮助

编辑:您还可以通过以下方式提供参数:

QTimer::singleShot(50, this, [=](){mySlot(arguments) ;}) ;

谢谢,我目前正在尝试另一种方法(删除并重新创建hide/showEvent上的所有回调,稍微干净一点,但需要更多处理),但我不认为我会在周末回家之前完成,所以如果它不起作用,我将在下周初尝试:)