【问题标题】:Qt: How to list hidden windows?Qt:如何列出隐藏的窗口?
【发布时间】:2017-10-05 13:45:04
【问题描述】:

我正在尝试从我的main.cppshow() 一个隐藏的 MainWindow(实际上此时所有窗口都被隐藏了)。我试着做这样的事情:

QList<QWindow*> windows = QApplication::allWindows();
for (int i = 0; i < windows.size(); ++i) {
    if (windows.at(i)->objectName() == "MainWindow")
        windows.at(i)->show();
}

但它不起作用。

QApplication::allWidgets() 的 Qt 文档中有一个注释:

注意:某些小部件可能会被隐藏。

好像这个函数没有列出隐藏的小部件,我想这与allWindows() 的情况相同,因为我在没有隐藏窗口并且工作正常的情况下测试了这段代码。

基本上在我做的void MainWindow::closeEvent函数中:

    event->ignore();
    hide();

然后我希望能够在单击应用程序图标时重新打开 MainWindow。

有没有人知道如何显示main.cpp 的隐藏窗口,或者可以指出我是否做错了什么?

编辑:这可能有效,我的问题出在完全不同的地方。

【问题讨论】:

  • 您是否尝试过这里的示例代码:doc.qt.io/qt-5/qapplication.html#topLevelWidgets?根据文档,它应该可以工作。
  • 很有趣,它也不起作用。
  • 但这表明我提到的那些函数确实列出了隐藏文件,只是由于某种原因它们不能像我所期望的那样工作。
  • 你怎么知道你的窗口是隐藏的?也许它根本不存在?
  • 我现在正在测试的是,“X”关闭按钮只会隐藏应用程序,再次单击图标会显示上一个窗口。因此,我可以通过单击图标托盘中的“隐藏图标”(不确定我是否使用正确的词汇)返回到以前的状态 - 这就是我假设窗口仍然存在的原因。

标签: qt window show


【解决方案1】:

在Qt对象树中查找所有特定类型窗口的方法可以缩短:

http://doc.qt.io/qt-5/qobject.html#findChildren

QList <QMainWindow *> mainWindows = qApp->findChildren<QMainWindow *>();
foreach(QMainWindow * w, mainWindows)
{
    qDebug() << "Found a main window" << w->objectName() 
        << "isVisible?" << w->isVisible();
}

http://doc.qt.io/qt-5/qobject.html#findChild

或者如果你知道 qobject 的名称:

QMainWindow * w = qApp->findChild<QMainWindow *>("My Named MainWindow");
if(w)
{
    qDebug() << "Found" << w->objectName() << "isVisible?" << w->isVisible();
}

findChildfindChildren 可用于任何 QObject 或 QObject 的子类,并可用于反射出指向其任何子类的指针。

MyMainWindow * w = qApp->findChild<MyMainWindow *>();

此外,如果您希望任何 QWidget 不死或关闭应用程序(如果它是最后一个要关闭的窗口),则使用:

w->setAttribute(Qt::WA_DeleteOnClose, false);

http://doc.qt.io/qt-5/qguiapplication.html#quitOnLastWindowClosed-prop

qApp->setQuitOnLastWindowClosed(false);

但是你必须在代码中明确地放置qApp-&gt;close()

与这一切相关的另一个工具是qobject_cast;我喜欢将它与 QObject::sender() 一起使用;

// some slot connected to by multiple sources
void mySlot()
{
    QPushButton * b = qobject_cast<QPushButton *>(QObject::sender());
    if(b)
    {
       qDebug() << "Push Button triggered" << Q_FUNC_INFO;
       b->setText("Ouch");
       b->setDisabled(true);
    }
}

希望对您有所帮助。

【讨论】:

  • 谢谢@phyatt!非常感谢您的帮助,但不知何故它对我不起作用,我真的不知道为什么。基本上问题是列表是空的,即使我所做的只是隐藏主窗口并且应用程序仍在运行,当我通过任务栏中的隐藏图标托盘访问它时,我回到以前的状态而不是新的主窗口或像这样的任何东西。
  • 听起来好像deleteLater 在你的主窗口上被调用了。可能是因为没有其他对象有指向它的指针,而且您看不到它,QEventLoop 清理了它。您能否以其他方式存储指向主窗口的指针,以便系统托盘中的QMenuItemQAction 可以找到该指针?在主窗口的析构函数中添加打印语句,并在 closeEvent 中添加打印语句。
  • 我知道出了什么问题,我以前不考虑这个是愚蠢的。每次我想重新打开应用程序时,我实际上只是在创建同一个应用程序的另一个实例。该应用程序使用互斥锁,如果应用程序中已经运行它,它只会显示一条消息,表明该应用程序已经打开但没有创建任何窗口,因此显然没有任何窗口要列出。无论如何,非常感谢@phyatt,我将您的答案标记为正确,因为它确实回答了我最初的问题。
猜你喜欢
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2013-09-03
  • 1970-01-01
相关资源
最近更新 更多