приложение на следующий день перестает делать рендеринг после пробуждения - PullRequest
0 голосов
/ 07 июня 2019

Я работаю над приложением на основе PyQt 5.12.2, оно упаковано как приложение Mac и использует QtQuick / QML для своего пользовательского интерфейса.См. https://github.com/manuel-koch/gitover/tree/Workaround_stuck_ui_renderer

Каждое утро после начала работы (открывая крышку ноутбука) приложение выглядит неработающим:

  • Я могу нажимать на элементы пользовательского интерфейса и, например, пункты главного менюизмените соответственно
  • Я могу запускать действия с помощью главного меню или сочетаний клавиш

НО сам интерфейс выглядит застрявшим, он ничего не рендерит, например, не подсвечивая вещи после того, как якликнул / выбрал видимые элементы и не выполняет рендеринг на основе изменений базовых объектов Qt бизнес-логики.

Т.е. приложение работает нормально, за исключением того, что пользовательский интерфейс не выполняет рендеринг!?

Iможно обойти эту проблему, вручную

  • , открыв диалоговое окно about и закрыв его
  • , изменив размер окна

После этого проблема исчезает, а пользовательский интерфейс продолжает повторную визуализацию(до следующего утра).

Я пытался реализовать обходной путь, который программно выполняет эти два простых шага (изменение размера главного окна, открытие / закрытие диалогового окна) всякий раз, когда онообнаруживает пробуждение от более длительного периода бездействия (то есть повторяющийся запланированный QTimer не срабатывает в течение достаточно долгого времени).

def size_window(wnd, w, h):
    if w is not None:
        wnd.setProperty("width", w)
    if h is not None:
        wnd.setProperty("height", h)

def resize_window(wnd):
    LOGGER.info("Workaround: resize window")
    w = wnd.width()
    h = wnd.height()
    size_window(wnd, w - 32, h - 32)
    size_window(wnd, w, h)

def open_and_close_about_dlg(wnd):
    LOGGER.info("Workaround: opening about dialog")
    aboutDialog = wnd.findChildren(QObject, "theAboutDialog")[0]
    try:
        QMetaObject.invokeMethod(aboutDialog, "openDialog")
        QTimer.singleShot(50, lambda: QMetaObject.invokeMethod(aboutDialog, "closeDialog"))
    except:
        LOGGER.exception("Failed to apply workaround")

def fix_hanging_qml_renderer(wnd):
    resize_window(wnd)
    open_and_close_about_dlg(wnd)

Но этот обходной путь, по-видимому, не имеет такого же эффекта, как выполнение его вручную!Т.е. пользовательский интерфейс по-прежнему не перерисовывается после применения обходного пути, запускаемого программным способом.

...