Подтвердить что ты не робот

Как переключить "всегда сверху" на QMainWindow в Qt, не вызывая мерцание или вспышку?

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 без этого "мигающего" побочного эффекта?

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Ну, для решения я решил, что посмотрю в источниках 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
}

Ответ 3

Протестировано с помощью

  • 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();
    }