【问题标题】:Activate window激活窗口
【发布时间】:2009-06-27 15:12:10
【问题描述】:

我有一个 QMainWindow。它有这个参数:

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

在 showEvent 调用后,我的窗口显示但未激活。 我试图重载显示功能:

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

但这对我没有帮助。

编辑: 当我评论行时

this->setWindowFlags(Qt::Tool);

一切正常,但我需要工具标志。 有什么想法吗?

编辑:

  • 操作系统:Linux
  • 编程语言:c++
  • Qt 版本:4.5.1

【问题讨论】:

    标签: c++ qt show


    【解决方案1】:

    Windows 管理器决定

    在我开始之前:正如elcucoJavier 所指出的,焦点策略和窗口布局的其他方面(例如标题栏)属于对各自窗口管理器的实质性扩展,Qt 可能会限制控制。要查看这一点,只需查看具有“focus follows mouse”策略的用户界面。在这些情况下,窗口管理器可能会忽略 Qt 的焦点请求。出于这个原因,Qt 文档将许多相应的标志称为“提示”。因此,一些建议的解决方案可能适合您,也可能不适合您。

    QApplication::setActiveWindow()

    尽管如此,e.tadeu's 使用 QApplication::setActiveWindow() 的解决方案对我来说适用于 Windows 和带有 Gnome 的 Ubuntu。我使用以下代码对其进行了测试。抱歉,它是使用 PyQt 的 Python(我使用这些问题来了解一些有关 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_SHOWNOACTIVATE 标志的ShowWindow() 函数,如果您设置Qt::Tool 标志,则显示具有WS_EX_TOOLWINDOW 样式的窗口。您可以轻松地将SW_SHOWNOACTIVATE 替换为您想要的任何内容。 Linux应该是一样的。显然也不推荐。

    【讨论】:

      【解决方案2】:

      尝试使用 QApplication::setActiveWindow()

      【讨论】:

        【解决方案3】:

        最初的苹果人机界面指南(*)说工具箱窗口“总是在顶部,但从未激活”。它还建议不要在它们上使用文本框,正是因为缺乏激活状态反馈。

        检查其他“重工具箱”应用的行为方式。我隐约记得至少 GIMP 和 InkScape 在这方面看起来很不一样。

        正如elcuco 所说,窗口管理器可以使用Qt 的标志为所欲为。另外,在 KDE、Gnome、fluxbox 等下肯定会有所不同。

        (*):很棒的文档!有点过时;但工具窗口已经被使用并考虑过

        【讨论】:

          【解决方案4】:

          哪个操作系统?哪个 Qt4?

          在 Linux 上,你注定要失败,窗口管理器可以忽略你告诉他的内容。请继续考虑。

          【讨论】:

            【解决方案5】:

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

            另外,如果可能的话,也许您最好尝试通过其他方式实现您需要 Qt::Tool 的任何效果?

            【讨论】:

              【解决方案6】:

              关于Qt::Tool WindowFlags 引用Qt文档

              表示该小部件是一个工具 窗户。工具窗口通常很小 窗口标题比平常小 酒吧和装饰,通常用于 工具按钮的集合。它在那里 是父母,工具窗口将 始终保持在它之上。如果有 不是父母,您可以考虑使用 Qt::WindowStaysOnTopHint 也是如此。如果 窗口系统支持它,一个工具 窗户可以用一个装饰 稍微轻一点的框架。它也可以 结合Qt::FramelessWindowHint

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

              【讨论】:

                【解决方案7】:

                只需在setWindowFlags() 之后调用show()

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-08-06
                  • 2018-04-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多