延迟检查小部件是否存在

时间:2018-08-30 16:58:50

标签: 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().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的命令,在这种情况下非常有用。我刚刚通过nukescripts.utils.executeDeferred进行了快速测试,但是即使睡了一秒钟也没用。

1 个答案:

答案 0 :(得分:0)

您可以使用QTimer :: singleShot将方法延迟x毫秒。

例如: 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) ;
     }
}

请谨慎操作,因为您对这50ms期间可能发生的情况没有任何保证。因此,这不是一种“尽快执行”的交易。还应注意避免无限递归。 希望对您有所帮助。

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

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