Активировать окно

У меня есть QMainWindow. Он имеет следующие параметры:

this->setWindowFlags(Qt::Tool);
this->setFocusPolicy(Qt::StrongFocus);
this->setAttribute(Qt::WA_QuitOnClose,true);

После вызова showEvent мое окно отображается, но неактивно. Я попытался перегрузить функцию show:

...    
QMainWindow::showEvent(event);
this->activateWindow();
...

Но это мне не помогает.

EDIT: Когда я прокомментировал строку

this->setWindowFlags(Qt::Tool);

все работало нормально, но мне нужен флаг инструмента. Любые идеи?

EDIT:

  • ОС: Linux
  • Язык программирования: С++
  • Версия Qt: 4.5.1

Ответы

Ответ 1

Менеджер Windows решает

Прежде чем начать: как указано elcuco и Хавьер, политика фокусировки и другие аспекты макет окна (например, строка заголовка) относится к существенному расширению для соответствующего менеджера окон, а Qt может иметь ограниченный контроль. Чтобы увидеть это, просто посмотрите на пользовательский интерфейс, в котором есть " focus follow mouse". В этих случаях диспетчер окон может игнорировать запрос фокуса Qt. По этой причине документация Qt вызывает многие соответствующие флаги "подсказки". Следовательно, некоторые из предлагаемых решений могут или не могут работать для вас.

QApplication:: SetActiveWindow()

Это не выдерживает, решение e.tadeu использовать QApplication::setActiveWindow() работает для меня как для Windows, так и для Ubuntu с Gnome. Я проверил его со следующим кодом. Извиняется, что это Python с использованием PyQt (я использую такие вопросы, чтобы узнать немного о PyQt). Вам должно быть довольно легко прочитать его и перевести на С++.

import sys

from PyQt4 import QtGui
from PyQt4 import QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)

        # main window
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Test')

        # text editor
        self.textEdit = QtGui.QTextEdit()
        self.setCentralWidget(self.textEdit)

    def closeEvent(self, event):
        QtGui.QApplication.instance().quit()

#main
app = QtGui.QApplication(sys.argv)
testWindow = MainWindow()
testWindow.setWindowFlags(QtCore.Qt.Tool)
testWindow.show()
app.setActiveWindow(testWindow)
app.exec_()

Обратите внимание, что вам нужно добавить некоторую обработку события закрытия testWindow, потому что приложение не выходит автоматически, если вы закрываете окно Qt::Tool.

Файл grabKeyboard() Hack

Если это не сработает для вас, может потребоваться следующий взлом. Я предполагаю, что у вас есть окно в активном приложении. Затем вы можете использовать grabKeyboard() для перенаправления ввода. Окно Qt::Tool не получает фокус, но получает вход. Следующий основной код демонстрирует это (другой код остается неизменным).

#main
app = QtGui.QApplication(sys.argv)
testWindow = MainWindow()
testWindow.setWindowFlags(QtCore.Qt.Tool)
testWindow2 = MainWindow()   # second window which is active
testWindow2.show()
testWindow.show()
testWindow.textEdit.grabKeyboard()
app.exec_()

В основном, хотя окно testWindow2 является активным, весь введенный текст отображается в testWindow.textEdit. Это не приятно, я знаю...

Создание собственного окна

Вы получаете максимальную гибкость (и создаете большую часть работы для себя), развертывая собственный макет окна. Идея описана в следующем FAQ.

Другие "решения"

Вы можете напрямую вызвать соответствующую функцию API оконного менеджера, чтобы получить желаемый результат (явно против самой причины использования Qt в первую очередь). Вы также можете взломать исходный код Qt. Например, в Windows Qt использует ShowWindow() с флагом SW_SHOWNOACTIVATE, чтобы показать окно со стилем WS_EX_TOOLWINDOW, если вы установите флаг Qt::Tool. Вы легко можете заменить SW_SHOWNOACTIVATE тем, что хотите. Linux должен быть таким же. Также не рекомендуется.

Ответ 2

В оригинальном руководстве по человеческому интерфейсу Apple (*) сказано, что окна панели инструментов "всегда сверху, но не активированы". Он также советует не использовать текстовые поля на них, именно потому, что отсутствие обратной связи с активацией.

Проверьте, как ведут себя другие приложения с тяжелыми приложениями. Я слабо вспоминаю, что по крайней мере GIMP и InkScape кажутся очень разными в этом аспекте.

Как сказал elcuco, оконный менеджер может делать все, что захочет, с флагами Qt. Кроме того, в KDE, Gnome, fluxbox, конечно, было бы иначе, что угодно.

(*): отличный документ! несколько устаревший; но окна инструментов уже использовались и считались

Ответ 3

Попробуйте использовать QApplication:: setActiveWindow()

Ответ 4

Какая операционная система? Какой Qt4?

В Linux вы обречены, диспетчер окон может игнорировать то, что вы ему говорите. Держите его на рассмотрении.

Ответ 5

То же самое происходит, если вы просто делаете его обычным QWidget вместо QMainWindow?

Кроме того, возможно, вам лучше попытаться достичь любого эффекта, который вам нужен Qt:: Tool, если это возможно?

Ответ 6

Относительно Qt:: Tool WindowFlags Чтобы представить документацию Qt

Указывает, что виджет является инструментом окно. Окно инструмента часто является небольшим окно с наименьшим, чем обычно, заголовком бар и украшения, обычно используемые для коллекции кнопок инструментов. Это там является родителем, окно инструмента всегда быть на вершине. Если здесь не является родителем, вы можете рассмотреть возможность использования Qt:: WindowStaysOnTopHint. Если оконная система поддерживает его, инструмент окно может быть украшено немного более легкая рама. Это также может быть в сочетании с Qt:: FramelessWindowHint

Кажется, что флаги являются проблемой, и использование Qt:: WindowStaysOnTopHint должно решить вашу проблему.

Ответ 7

Просто позвоните show() после setWindowFlags().