【问题标题】:Centrally track opened and closed windows in Qt在 Qt 中集中跟踪打开和关闭的窗口
【发布时间】:2019-04-01 23:11:14
【问题描述】:

我需要 QApplication 中的一些虚函数/信号/事件,集中通知应用程序中任何打开和关闭的窗口(提供指向窗口对象的指针;包括 QMainWindow、QDialog、基于 QWidget 的窗口)。

这应该可以在手动注册所有窗口实例且无需手动操作每个实例(例如,通过在每个窗口对象上安装事件过滤器或连接)的情况下工作。 此外,不必从某个接口类或类似类中对跟踪的窗口进行子类化。

那么,Qt 中跟踪应用程序中所有打开和关闭的窗口的最佳方法是什么?

【问题讨论】:

    标签: c++ qt window


    【解决方案1】:

    你必须重写QApplication(或QGuiApplication)的notify方法:

    #include <QtWidgets>
    
    class Application: public QApplication
    {
    public:
        using QApplication::QApplication;
        bool notify(QObject *receiver, QEvent *e) override
        {
            if(receiver->isWindowType()){
                if(e->type() == QEvent::Show){
                    qDebug()<< receiver << "show";
                }
                else if (e->type() == QEvent::Close) {
                    qDebug()<< receiver << "close";
                }
            }
            return QApplication::notify(receiver, e);
        }
    };
    
    int main(int argc, char *argv[])
    {
        Application a(argc, argv);
        QMainWindow m;
        QDialog d;
        QWidget w;
        m.show();
        d.show();
        w.show();
        return a.exec();
    }
    

    更新:

    #include <QtWidgets>
    
    class Application: public QApplication
    {
    public:
        using QApplication::QApplication;
        bool notify(QObject *receiver, QEvent *e) override
        {
            if(receiver->isWidgetType()){
                QWidget *w = qobject_cast<QWidget *>(receiver);
                if(w->isWindow()){
                    if(e->type() == QEvent::Show){
                        qDebug()<< w << "show";
                    }
                    else if (e->type() == QEvent::Close) {
                         qDebug()<< w << "close";
                    }
                }
            }
            return QApplication::notify(receiver, e);
        }
    };
    

    【讨论】:

    • 我尝试的是保存/恢复窗口配置。事实证明,由于 Qt 的限制,它不适用于此精细代码:Qt5 中的isWindowType() 使接收器成为从 QWindow 派生的对象(而不是 Qt4 中的 QWidget)。对于 QWidget 应用程序,接收器是 QWidgetWindow。 Q(Widget)Window 没有实现保存/恢复所必需的normalGeometry()。 QWidgetWindow 也是 Qt 的私有 API。所以没有合法的方式来访问底层的 QWidget。我决定改用isWidgetType()。但是,这将我的代码限制为基于 QWidget 的应用程序。
    • @Silicomancer 1) 我已经展示了如何与 QWidget 一起使用 2) 您还想使用哪些其他类型的窗口?
    • 目前只有基于 QWidget 的窗口。所以目前这不是问题。但是我对您的示例添加了另外两个修改:我比较了 windowType() (以忽略工具提示之类的内容)并且我没有使用关闭事件而是隐藏事件,因为我发现 QDialog 窗口在 accept() 上没有收到关闭事件或拒绝()。
    • @Silicomancer 如果你想改进过滤器,你应该做更多的演员:if(QDialog * dialog = qobject_cast&lt;QDialog *&gt;(receiver)){/* is QDialog */ }
    • 是的,我这样做了。此外,我决定跳过在最小化/最大化窗口时也会触发的自发事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多