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 的想法,我开发了两个 类、MyWidget
和 MyMainWindow
,它们可以在它们的构造函数中使用它们自己和彼此创建子项 windows,它将拥有自己的任务栏条目,同时仍充当其父项 windows 的子项(即在父项 window 终止时自动关闭并销毁)。 MyWidget
替换 QWidget
,MyMainWindow
替换 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
.
上看到更好的做法
我正在使用 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
.
希望对您有所帮助。
主要基于海报 Konstantin T. 和 Mike 的想法,我开发了两个 类、MyWidget
和 MyMainWindow
,它们可以在它们的构造函数中使用它们自己和彼此创建子项 windows,它将拥有自己的任务栏条目,同时仍充当其父项 windows 的子项(即在父项 window 终止时自动关闭并销毁)。 MyWidget
替换 QWidget
,MyMainWindow
替换 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
.