Qt:强制childwindow有自己的任务栏入口

Qt: Force child window to have its own task bar entry

我正在使用 Qt 5 和 C++,我想强制我的一些 child windows 有自己的任务栏条目。现在,我可以创建 parentless QWidgets 并使用 signal-slot 机制在主 window (QMainWindow) 关闭时关闭那些 windows .

然而,随着我添加越来越多的 parents 和 childs,整个 signal-slot 技术将变得乏味(不是吗?)而且我确信 Qt 已经有一个我可以使用的功能。我看过 this小学和中学 Windows 部分讨论了我正在尝试做的事情。它说:

In addition, a QWidget that has a parent can become a window by setting the Qt::Window flag. Depending on the window management system such secondary windows are usually stacked on top of their respective parent window, and not have a task bar entry of their own.

我知道我需要将我的 QWidgets 设置为 Primary Windows 但我不知道如何设置。

所以我尝试了:

// when a QMainWindow's (this) push button is clicked:
QWidget* newWindow = new QWidget(this, Qt::Window);
newWindow->show();

它没有给我想要的行为。如何将 newWindow 设置为 主要 Window,同时仍将 this 保持为 parent?

我现在没有在 Qt 中执行此操作的本机方法。但是你可以使用它 signal/slot 在你至少有一千个 windows 之前它绝对不会对处理器造成严重的负担。为此,您可以实施自己的子父机制。

例如:

class myOwnWidget: public QWidget{
    Q_OBJECT
public:
    myOwnWidget(myOwnWidget* parent = 0):
        QWidget(){
        if(parent){
            connect(parent,SIGNAL(close()), this,SLOT(deleteLater()));
        }
    }

    void closeEvent(QCloseEvent* e){
        emit close();
        QWidget::closeEvent(e);
    }

signals:
    void close();
};

class PrimaryWindow : public myOwnWidget{
    PrimaryWindow(myOwnWidget *parent):
        myOwnWidget(parent)
    {
        //your constructor here
    }

}

使用:

PrimaryWindow * rootWindows = new PrimaryWindow();
PrimaryWindow * childWin = new PrimaryWindow(rootWindows);

在代码 PrimaryWindow 中创建时没有 Qt-parent,但是对于关闭子 windows 你应该从 myOwnWidget.

继承你所有的 windows

希望对您有所帮助。

主要基于海报 Konstantin T. 和 Mike 的想法,我开发了两个 类、MyWidgetMyMainWindow,它们可以在它们的构造函数中使用它们自己和彼此创建子项 windows,它将拥有自己的任务栏条目,同时仍充当其父项 windows 的子项(即在父项 window 终止时自动关闭并销毁)。 MyWidget 替换 QWidgetMyMainWindow 替换 QMainWindow(如果需要这样的行为)。

my_widget.h:

#ifndef MY_WIDGET_H
#define MY_WIDGET_H

#include <QWidget>
#include <QMainWindow>

class MyMainWindow;

class MyWidget : public QWidget{

    Q_OBJECT

public:
    MyWidget(MyWidget* parent = 0){
        if(parent){
            connect(parent, SIGNAL(window_closed()),
                    this, SLOT(close()));
            connect(parent, SIGNAL(destroyed(QObject*)),
                    this, SLOT(deleteLater()));
        }
    }

    MyWidget(MyMainWindow* parent);

    void closeEvent(QCloseEvent* event){
        emit window_closed();
        QWidget::closeEvent(event);
    }

signals:
    void window_closed();
};

class MyMainWindow : public QMainWindow{

    Q_OBJECT

public:
    MyMainWindow(MyMainWindow* parent = 0){
        if(parent){
            connect(parent, SIGNAL(window_closed()),
                    this, SLOT(close()));
            connect(parent, SIGNAL(destroyed(QObject*)),
                    this, SLOT(deleteLater()));
        }
    }

    MyMainWindow(MyWidget* parent){
        connect(parent, SIGNAL(window_closed()),
                this, SLOT(close()));
        connect(parent, SIGNAL(destroyed(QObject*)),
                this, SLOT(deleteLater()));
    }

    void closeEvent(QCloseEvent* event){
        emit window_closed();
        QMainWindow::closeEvent(event);
    }

signals:
    void window_closed();
};

#endif // MY_WIDGET_H

my_widget.cpp:

#include "my_widget.h"

MyWidget::MyWidget(MyMainWindow* parent){
    connect(parent, SIGNAL(window_closed()),
            this, SLOT(close()));
    connect(parent, SIGNAL(destroyed(QObject*)),
            this, SLOT(deleteLater()));
}

示例main.cpp:

#include <QApplication>
#include "my_widget.h"

int main(int argc, char* argv){
    QApplication a(argc, argv);

    MyWidget mw1{new MyWidget};
    mw1.setWindowTitle("ctor: MyWidget(MyWidget*)");
    mw1.show();

    MyMainWindow mmw1{&mw1};
    mmw1.setWindowTitle("ctor: MyMainWindow(MyWidget*)");
    mmw1.show();

    MyMainWindow mmw2{&mmw1};
    mmw2.setWindowTitle("ctor: MyMainWindow(MyMainWindow*)");
    mmw2.show();

    MyWidget mw2{&mmw2};
    mw2.setWindowTitle("ctor: MyWidget(MyMainWindow*)");
    mw2.show();
    return a.exec();
}

所以 window 链是: mw1 -> mmw1 -> mmw2 -> mw2 其中任何关闭的 window 也会破坏其右侧的所有 windows 和所有 windows该链将有自己的任务栏条目。

我确信在 my_widget.h 中有更优雅的方法来定义构造函数,但作为新手,这对我来说很有效,可以获得我需要的确切行为。我很高兴在 my_widget.h.

上看到更好的做法