Шаблоны проектирования плохие.
На самом деле, шаблоны проектирования не .
Вы можете написать плохой код и похоронить его под кучей шаблонов. Используйте синглтоны как глобальные переменные и состояния как goto. Безотносительно.
Шаблон проектирования является стандартным решением для конкретной проблемы, но требует, чтобы вы сначала поняли проблему. Если вы этого не сделаете, шаблоны проектирования станут частью проблемы для следующего разработчика.
Диспетчер Windows решает
Перед тем, как я начну: Как указано elcuco и Хавьер , политика фокуса и другие аспекты компоновки окон (например, строка заголовка) в значительной степени принадлежит соответствующему диспетчеру окон, и Qt может иметь ограниченный контроль. Чтобы убедиться в этом, просто взгляните на пользовательский интерфейс с политикой « фокус следует за мышью ». В этих случаях диспетчер окон может игнорировать запрос фокуса 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
.
Взлом grabKeyboard ()
Если это не сработает для вас, возможно, следующий взлом. Я предполагаю, что у вас есть активное окно в вашем приложении. Затем вы можете использовать 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
на что угодно. Линукс должен быть таким же. Ясно, что тоже не рекомендуется.
Произойдет ли то же самое, если вы просто сделаете его обычным QWidget вместо QMainWindow?
Кроме того, возможно, вам лучше попытаться достичь того эффекта, который вам нужен Qt :: Tool для другими способами, если это возможно?
Какая операционная система? Какой Qt4?
В Linux вы обречены, оконный менеджер может игнорировать то, что вы ему говорите. Держите это в поле зрения.
Попробуйте использовать QApplication :: setActiveWindow ()
Относительно Qt :: Tool WindowFlags Цитата из документации Qt
Указывает, что виджет является инструментом окно. Окно инструментов часто бывает небольшим окно с меньшим, чем обычно, заголовком бар и украшение, обычно используемые для коллекции кнопок инструментов. Это там является родителем, окно инструментов будет всегда быть на вершине. Если здесь не родитель, вы можете рассмотреть возможность использования Qt :: WindowStaysOnTopHint тоже. Если оконная система поддерживает это, инструмент окно можно украсить несколько более светлый корпус. Это также может быть в сочетании с Qt :: FramelessWindowHint
Кажется, что флаги - это проблема, и использование Qt :: WindowStaysOnTopHint должно решить вашу проблему.
В исходных правилах пользовательского интерфейса Apple (*) говорилось, что окна панели инструментов были «всегда вверху, но никогда не активировались». Он также не рекомендует использовать на них текстовые поля именно из-за отсутствия обратной связи о состоянии активации.
Проверьте, как ведут себя другие приложения с «тяжелым набором инструментов». Я смутно припоминаю, что по крайней мере GIMP и InkScape кажутся очень разными в этом аспекте.
Как сказал elcuco , оконный менеджер может делать с флагами Qt все, что захочет. Кроме того, все будет по-другому в KDE, Gnome, fluxbox и т. Д.
(*): отличный документ! несколько устаревший; но окна инструментов уже использовались и рассматривались