Задержка проверки, если виджет существует - PullRequest
0 голосов
/ 30 августа 2018

Я испытывал головную боль, пытаясь работать с пристыкованными панелями 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, но он не очень чистый и может привести к проблемам.

У Майи была команда под названием evalDeferred, которая была очень полезна в подобных случаях. У меня только что был быстрый тест с nukescripts.utils.executeDeferred, но даже со сном на секунду это не сработало.

1 Ответ

0 голосов
/ 31 августа 2018

Вы можете отложить метод на x мс, используя QTimer :: singleShot.

Например: QTimer::singleShot(50, this, &MyWidget::mySlot) ; выполнит слот mySlot через 50 мс после вызова этой инструкции. Это эквивалентно созданию 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) ;}) ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...