2017-02-16 10 views
1

Мне действительно нужно сделать мое окно, чтобы оно оставалось сверху на Windows, но для Windows это не выглядит willing to allow me.QML в Windows: заставьте окно оставаться на вершине

Я не могу использовать обходной путь с установкой значений реестра, потому что я не могу попросить пользователя выйти из системы/войти в систему.

Кроме того, я использую QML и решение с QWidget::raise() and QApplication::setActiveWindow(), кажется, не работает и потому, что мне не удалось получить корневой объект QML как указатель QWidget со следующим кодом:

QWidget* mainWin = qobject_cast<QWidget*>(engine.rootObjects().at(0)); 
if (mainWin) 
{ 
    mainWin->raise(); 
    QApplication::setActiveWindow(mainWin); 
    mainWin->activateWindow(); 
} 

Я также попытался сделать окно активным справа от QML:

window.raise() 
window.requestActivate() 

но не везет.

Есть ли способ ввернуть окно поверх Windows без изменения реестра и, предпочтительно, из QML?

Edit: используемые в настоящее время окна флагов:

Qt.Popup 
Qt.FramelessWindowHint 
Qt.WindowStaysOnTopHint 
Qt.CustomizeWindowHint 
Qt.BypassWindowManagerHint 
Qt.MSWindowsFixedSizeDialogHint 

Я развертывание Qt 5.7 приложения на Windows, 10 x 64 машины. я нашел эти два исправления:

, из которых я могу сделать вывод, что QWidget :: activateWindow() и QWindow :: requestActive() должен работать на Windows XP и Windows 7

Вот мой mcve, как просили @derM:

import QtQuick 2.7 
import QtQuick.Window 2.2 

Window { 
    flags: Qt.WindowStaysOnTopHint 

    width: 100 
    height: 100 
    visible: true 
} 

Он был скомпилирован под Windows 10 x64 с MinGW x32.

Легче способ воспроизвести: запустить в командной строке

timeout 5 && debug\Test.exe 

где отлаживать \ TEST.exe является путь к mcve двоичном, а затем откройте Проводник и перейдите куда-нибудь. Когда откроется окно, оно не будет на переднем плане.

Harder way: Если вы просто запустите его, окно останется на вершине, как должно. Но если вы нажмете кнопку Run в Qt Creator и переключите фокус (я полагаю, фокус мыши должен быть изменен, просто нажав Alt + Tab won`t help) другому процессу (в моем случае - File Explorer), окно отображается под текущим активным окном Проводника, и даже если я его подниму, щелкнув, он пойдет в фоновом режиме, как только я выберу любое другое приложение.

Реальное приложение запускается из службы, поэтому при запуске приложения часто будет приложение с фокусом мыши.Я полагаю, что Qt возможность вывести окно на передний план реализуется с помощью SetForegroundWindow API вызова, который отмечает следующие ограничения в слове: поэтому интерьер

  • Процесс является основным процессом.
  • Процесс был начат процессом переднего плана.
  • Процесс получил последнее событие ввода.
  • Не существует процесса переднего плана.
  • Процесс отлаживается.
  • Процесс переднего плана не является современным приложением или стартовым экраном.
  • Передний план не заблокирован (см. LockSetForegroundWindow).
  • Истек срок блокировки переднего плана (см. - SPI_GETFOREGROUNDLOCKTIMEOUT в SystemParametersInfo).
  • Нет меню.

Так что, возможно, вообще-то можно привести окно на передний план, если процесс был запущен службой, а не пользователем (то есть процесс не был активным процессом во время запуска).

+0

Просто, чтобы убедиться: вы говорите о QML не о QtWidgets, не так ли? – derM

+0

@derM Точно, но я предполагаю, что в QML-типах и QWidgets существует общая механика, поэтому я обратил внимание на ошибки, связанные с QWidgets. Я не нашел ничего, кроме флага Qt.WindowStaysOnTopHint, который мог бы помочь с проблемой с чистой стороны QML. –

+0

Хорошо, похоже, ошибка. Я выложу какой-то хак, который обходит его для меня. – derM

ответ

2

Как вы уже опубликовали: если окно создано из процесса переднего плана, мы просто убедитесь, что наш процесс является передним планом перед тем, как мы создадим окно.

import QtQuick 2.7 
import QtQuick.Window 2.2 

Item { 
    id: root 

    Component { // Like a splash screen: Claim to be foreground process, 
       // then create main window. 
     id: winInit 
     Window { 
      flags: Qt.WindowStaysOnTopHint 
      width: 1 
      height: 1 
      Component.onCompleted: { 
       requestActivate() 
       mainWin.createObject(root) 
      } 
     } 
    } 

    Component { 
     id: mainWin 
     Window { 
      flags: Qt.WindowStaysOnTopHint 
      width: 100 
      height: 100 
      visible: true 
     } 
    } 

    Component.onCompleted: { 
     var w1 = winInit.createObject(null) 
     w1.destroy() 
    } 
} 
+0

Я должен был заметить, что я использовал этот флаг, но в Windows он ничего не делает. –

+0

Для меня это работает на Win7 и Qt5.7. Какую версию вы используете? Можете ли вы предоставить [mcve] (http://stackoverflow.com/help/mcve)? – derM

+0

Я использую Qt 5.8 в Windows 10. Проблема с появлением окна на переднем плане кажется исправленной для Windows 7: https://bugreports.qt.io/browse/QTBUG-37435 –

 Смежные вопросы

  • Нет связанных вопросов^_^