激活窗口

14

我有一个QMainWindow窗口。它具有以下参数:

this->setWindowFlags(Qt::Tool);
this->setFocusPolicy(Qt::StrongFocus);
this->setAttribute(Qt::WA_QuitOnClose,true);
在 showEvent 被调用后,我的窗口已经显示但未激活。我尝试重载 show 函数:

...    
QMainWindow::showEvent(event);
this->activateWindow();
...
但这并没有帮助我。 编辑:当我注释掉那一行时。
this->setWindowFlags(Qt::Tool);

一切都运行良好,但我需要在工具标志中做些修改。有什么想法吗?

编辑:

  • 操作系统:Linux
  • 编程语言:C++
  • Qt版本:4.5.1
7个回答

14

窗口管理器决定

在我开始之前:正如elcucoJavier所指出的那样,焦点策略和窗口布局的其他方面(例如标题栏)在很大程度上属于相应的窗口管理器,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() 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使用带有标志SW_SHOWNOACTIVATEShowWindow()函数,以显示具有样式WS_EX_TOOLWINDOW的窗口,如果您设置了Qt::Tool标志。您可以轻松地将SW_SHOWNOACTIVATE替换为任何您想要的内容。Linux应该是一样的。显然也不推荐。


4

尝试使用QApplication::setActiveWindow()函数


4
原始的苹果人机界面准则(*)指出,工具箱窗口“始终置顶但从不激活”。它还建议不要在这些窗口上使用文本框,正是因为缺乏激活状态反馈。
检查其他“工具箱重型”应用程序的行为。我模糊地记得至少GIMP和InkScape在这方面非常不同。
正如 elcuco 所说,窗口管理器可以随意使用Qt的标志。此外,在KDE、Gnome、fluxbox等情况下也会有所不同。
(*):伟大的文档!有点过时;但工具窗口已经被使用并得到考虑。

1

使用哪个操作系统?使用哪个Qt4版本?

在Linux上,你注定会遇到问题,窗口管理器可能会忽略你的指令。请谨慎考虑。


0
只需在 setWindowFlags() 后调用 show() 即可。

0

关于Qt::Tool WindowFlags,引用Qt文档的说法:

表示该小部件是一个工具窗口。工具窗口通常是一个带有比通常更小的标题栏和装饰的小窗口,通常用于集合工具按钮。如果有父级,则工具窗口将始终保持在其上方。如果没有父级,则还可以考虑使用Qt::WindowStaysOnTopHint。如果窗口系统支持,工具窗口可以用较轻的框架进行装饰。它也可以与Qt::FramelessWindowHint结合使用。

看起来标志是个问题,使用Qt::WindowStaysOnTopHint应该可以解决您的问题。


0

如果你只把它做成一个普通的QWidget而不是QMainWindow,会发生同样的事情吗?

另外,如果可能的话,也许你可以尝试通过其他方式来实现你需要使用Qt::Tool的效果?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接