简体   繁体   English

Qt:强制子窗口拥有自己的任务栏条目

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

I'm using Qt 5 and C++ and I want to force some of my child windows to have their own task bar entries.我正在使用 Qt 5 和 C++,我想强制我的一些子窗口拥有自己的任务栏条目。 Right now, I am able to create parentless QWidgets and use the signal-slot mechanism to close those windows when a main window (QMainWindow) is closed.现在,我能够创建无父 QWidget 并在主窗口 (QMainWindow) 关闭时使用信号槽机制来关闭这些窗口。

However as I add more and more parents and childs this whole signal-slot technique will get tedious (won't it?) and I am sure that Qt already has a feature I can use for this.然而,随着我添加越来越多的父母和孩子,整个信号槽技术将变得乏味(不是吗?),我确信 Qt 已经有一个我可以使用的功能。 I've seen this ;我见过这个 Primary and Secondary Windows section talks about what I'm trying to do.主要和次要 Windows部分讨论了我正在尝试做的事情。 It says:它说:

In addition, a QWidget that has a parent can become a window by setting the Qt::Window flag.此外,通过设置 Qt::Window 标志,具有父级的 QWidget 可以成为窗口。 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.根据窗口管理系统,此类辅助窗口通常堆叠在其各自父窗口的顶部,并且没有自己的任务栏条目。

I can see that I need to set my QWidgets as Primary Windows but I don't exactly know how.我可以看到我需要将 QWidgets 设置为主窗口,但我不完全知道如何。

So I tried:所以我试过:

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

It doesn't give me the behavior I want.它没有给我想要的行为。 How can I set newWindow as a Primary Window while still keeping this as its parent?如何设置newWindow作为主窗口,同时仍保持this作为它的父?

I don't now native method to do it in Qt.我现在不使用本机方法在 Qt 中执行此操作。 But you can use for it signal/slot it's definitely not create a serious burden on the processor until you have at least a thousand windows.但是您可以使用它的信号/插槽,它绝对不会对处理器造成严重负担,直到您至少拥有一千个窗口。 For it you can implement your own child parent mechanizme.为此,您可以实现自己的子父级机制。

For example:例如:

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
    }

} }

using:使用:

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

In code PrimaryWindow create without Qt-parent, but for closing child windows you should inherit all your windows from myOwnWidget .在没有 Qt-parent 的代码PrimaryWindow创建,但要关闭子窗口,您应该从myOwnWidget继承所有窗口。

Hope it help.希望有帮助。

Heavily based on posters Konstantin T.'s and Mike's ideas, I have developed two classes, MyWidget and MyMainWindow , which can use themselves and each other in their constructors to create child windows which will have their own task bar entries while still acting as children to their parent windows (ie getting automatically closed and destroyed upon termination of the parent window).很大程度上基于海报 Konstantin T. 和 Mike 的想法,我开发了两个类, MyWidgetMyMainWindow ,它们可以在构造函数中使用它们自己和彼此来创建子窗口,这些子窗口将有自己的任务栏条目,同时仍然充当孩子到它们的父窗口(即在父窗口终止时自动关闭和销毁)。 MyWidget replaces QWidget and MyMainWindow replaces QMainWindow if such a behavior is desired. MyWidget内容替换QWidgetMyMainWindow内容替换QMainWindow如果这样的行为是需要的。

my_widget.h: 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: 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()));
}

Example main.cpp:示例 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();
}

So the window chain is: mw1 -> mmw1 -> mmw2 -> mw2 where any window that is closed will also destroy all windows to its right and all windows in the chain will have their own task bar entries.所以窗口链是: mw1 -> mmw1 -> mmw2 -> mw2其中任何关闭的窗口也将销毁其右侧的所有窗口,并且链中的所有窗口都有自己的任务栏条目。

I'm sure there are more elegant ways of defining the constructors in my_widget.h , but as a newbie this worked for me to obtain the exact behavior I needed.我确信在my_widget.h有更优雅的定义构造函数的my_widget.h ,但作为一个新手,这对我来说是获得我需要的确切行为的方法。 I'd appreciate to see better practices on my_widget.h .我很高兴在my_widget.h上看到更好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM