You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置setQuitOnLastWindowClosed(false)后关闭Qt应用及多窗口切换问题

嘿,我来帮你搞定这个Qt多窗口切换的问题!你要的是主窗口(MainWindow)和两个子窗口(ChildWindow1、ChildWindow2)互切,同一时间只显示一个窗口,对吧?我把完整的实现思路和代码都整理好了,应该能解决你之前关闭子窗口时遇到的问题。

Qt多窗口切换完整实现方案

整体思路

  • 主窗口放置两个按钮,点击后隐藏自身并显示对应子窗口
  • 子窗口关闭时通过信号通知主窗口,让主窗口自动显示
  • 主窗口关闭时,因为子窗口以主窗口为父节点,会自动销毁,同时终止整个应用

代码实现

1. 主窗口(MainWindow)代码

头文件(mainwindow.h)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "childwindow1.h"
#include "childwindow2.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_openChild1Btn_clicked();
    void on_openChild2Btn_clicked();
    void showMainWindow(); // 子窗口关闭时触发,显示主窗口

private:
    Ui::MainWindow *ui;
    ChildWindow1 *child1;
    ChildWindow2 *child2;
};
#endif // MAINWINDOW_H

源文件(mainwindow.cpp)

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 初始化子窗口,设置主窗口为父节点,避免内存泄漏
    child1 = new ChildWindow1(this);
    child2 = new ChildWindow2(this);

    // 关联子窗口的关闭信号到主窗口的显示槽
    connect(child1, &ChildWindow1::closed, this, &MainWindow::showMainWindow);
    connect(child2, &ChildWindow2::closed, this, &MainWindow::showMainWindow);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_openChild1Btn_clicked()
{
    this->hide(); // 隐藏主窗口
    child1->show(); // 显示子窗口1
}

void MainWindow::on_openChild2Btn_clicked()
{
    this->hide();
    child2->show();
}

void MainWindow::showMainWindow()
{
    this->show(); // 重新显示主窗口
}

2. 子窗口(以ChildWindow1为例)代码

ChildWindow2的代码和ChildWindow1几乎完全一致,只需要把类名替换即可。

头文件(childwindow1.h)

#ifndef CHILDWINDOW1_H
#define CHILDWINDOW1_H

#include <QWidget>

namespace Ui {
class ChildWindow1;
}

class ChildWindow1 : public QWidget
{
    Q_OBJECT

public:
    explicit ChildWindow1(QWidget *parent = nullptr);
    ~ChildWindow1();

signals:
    void closed(); // 自定义信号,窗口关闭时发出

protected:
    void closeEvent(QCloseEvent *event) override; // 重写关闭事件

private:
    Ui::ChildWindow1 *ui;
};

#endif // CHILDWINDOW1_H

源文件(childwindow1.cpp)

#include "childwindow1.h"
#include "ui_childwindow1.h"
#include <QCloseEvent>

ChildWindow1::ChildWindow1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ChildWindow1)
{
    ui->setupUi(this);
}

ChildWindow1::~ChildWindow1()
{
    delete ui;
}

void ChildWindow1::closeEvent(QCloseEvent *event)
{
    emit closed(); // 发出关闭信号,通知主窗口显示
    event->accept(); // 接受关闭事件,窗口会隐藏(而非销毁,因为有父节点)
}

关键注意点

  • 子窗口父节点设置:将子窗口的父节点设为主窗口,这样主窗口关闭时子窗口会自动销毁,避免内存泄漏。
  • 自定义信号触发:重写子窗口的closeEvent,在关闭时发出closed信号,确保主窗口能及时收到通知并显示。
  • 窗口复用:这里采用复用子窗口实例的方式,每次点击按钮直接显示已创建的窗口,比每次创建新实例更高效。如果需要每次打开新窗口,可以在按钮点击时动态创建,并关联destroyed信号避免野指针。

这样应该就完全满足你的需求了,测试一下:点击主窗口按钮会切换到对应子窗口,关闭子窗口会自动回到主窗口,关闭主窗口整个应用就退出了。

内容的提问来源于stack exchange,提问作者Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:55:32