Как мне переключить «всегда сверху» для QMainWindow в Qt, не вызывая мерцания или вспышки? - PullRequest
22 голосов
/ 18 мая 2010
void MainWindow::on_actionAlways_on_Top_triggered(bool checked)
{
    Qt::WindowFlags flags = this->windowFlags();
    if (checked)
    {
        this->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
        this->show();
    }
    else
    {
        this->setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
        this->show();
    }
}

Приведенное выше решение работает, но поскольку setWindowFlags скрывает окно, его необходимо повторно отобразить, и, конечно, оно выглядит не очень элегантно. Итак, как мне переключить «всегда сверху» для QMainWindow без этого «мигающего» побочного эффекта?

Ответы [ 3 ]

19 голосов
/ 18 мая 2010

Nokia говорит нет :

Невозможно внести изменения в флаги окна после того, как окно было создано, не вызывая мерцания. Мерцание неизбежно, так как окно необходимо воссоздать.

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

Возможно, появится небольшая строка прогресса, которой нет в окне, скажем «Настройка свойств окна!» ... исчезнет окно, а затем вернется обратно, и закройте всплывающее окно индикатора выполнения.

16 голосов
/ 19 мая 2010

Что ж, для решения, которое я решил, я буду искать в источниках Mono, так как знаю, что класс .NET Form (System.Windows.Forms) имеет свойство TopMost.

Решение, которое я нашел для моей программы Qt, было:

void MainWindow::on_actionAlways_on_Top_triggered(bool checked)
{
#ifdef Q_OS_WIN
    // #include <windows.h>
    if (checked)
    {
        SetWindowPos(this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    }
    else
    {
        SetWindowPos(this->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    }
#else
    Qt::WindowFlags flags = this->windowFlags();
    if (checked)
    {
        this->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
        this->show();
    }
    else
    {
        this->setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
        this->show();
    }
#endif
}
0 голосов
/ 24 марта 2014

Проверено с

  • Qt 5.2.1 в Windows XP
  • Qt 5.2 на OS X 10.9

    void ConsoleUI::onAllwaysTop(bool checked)
    {
        Qt::WindowFlags flags = windowFlags();
        if (checked)
        {
            flags ^= Qt::WindowStaysOnBottomHint;
            flags |= Qt::WindowStaysOnTopHint;
        }
        else
        {
            flags ^= Qt::WindowStaysOnTopHint;
            flags |= Qt::WindowStaysOnBottomHint;
        }
        setWindowFlags(flags);
        show();
    }

...