Активировать окно - PullRequest
       27

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

14 голосов
/ 27 июня 2009

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

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

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

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

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

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

this->setWindowFlags(Qt::Tool);

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

EDIT:

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

Ответы [ 7 ]

14 голосов
/ 08 июля 2009

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

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

QApplication :: SetActiveWindow ()

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

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.

Захват для клавиатуры () 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 должен быть таким же. Понятно также не рекомендуется.

4 голосов
/ 04 июля 2009

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

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

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

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

4 голосов
/ 04 июля 2009

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

1 голос
/ 27 июня 2009

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

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

0 голосов
/ 12 апреля 2010

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

0 голосов
/ 04 июля 2009

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

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

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

0 голосов
/ 29 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...