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

QT C++ Widget应用中通过PushButton从子窗口返回主窗口的实现问题

How to Return to Main Window from Child Window in Qt Widgets App

Hey there! Let's fix this issue step by step. First, let's break down what's going wrong with your current code, then I'll show you two reliable ways to implement the "return to main window" functionality that fits Qt's best practices (and works correctly).

What's Wrong with Your Current Code?

Your line mainwindow = new MainWindow(this); is causing two key problems:

  1. Type Mismatch Error: The compiler error tells us that MainWindow's constructor expects a parameter of type Widget, but you're passing this (a pointer to your Crediti child window, which is a QWidget subclass). This mismatch is why the error pops up.
  2. Unnecessary New Window: Even if the error was fixed, creating a new MainWindow instance would open a brand new main window instead of showing the original one you had before opening the child window. That's not what you want—you just need to go back to the existing main window!

This is the cleanest way because it keeps your main window and child window decoupled (they don't need direct knowledge of each other's internal details). Here's how to do it:

Step 1: Add a Signal to Your Child Window (Crediti)

Edit your crediti.h file to define a custom signal that the child window will emit when the "return" button is clicked:

#ifndef CREDITI_H
#define CREDITI_H

#include <QWidget>

namespace Ui {
class Crediti;
}

class Crediti : public QWidget
{
    Q_OBJECT

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

// Add this signal declaration
signals:
    void returnToMain();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Crediti *ui;
};

#endif // CREDITI_H

Step 2: Emit the Signal in the Child Window's Button Slot

Update crediti.cpp to emit the signal and close the child window when the button is clicked:

#include "crediti.h"
#include "ui_crediti.h"

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

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

void Crediti::on_pushButton_clicked()
{
    // Emit the signal to tell the main window to show itself
    emit returnToMain();
    // Close the child window
    this->close();
}

Step 3: Connect the Signal in the Main Window

When you open the child window from MainWindow, connect the child's returnToMain signal to the main window's show() slot. Update your main window's button slot (the one that opens the child window) in mainwindow.cpp:

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

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

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

void MainWindow::on_openCreditiBtn_clicked()
{
    // Create the child window (no parent needed here)
    Crediti *creditiWindow = new Crediti();
    
    // Connect the child's signal to our main window's show() slot
    connect(creditiWindow, &Crediti::returnToMain, this, &MainWindow::show);
    
    // Hide the main window temporarily
    this->hide();
    
    // Show the child window
    creditiWindow->show();
    
    // Make sure the child window is deleted when closed to avoid memory leaks
    creditiWindow->setAttribute(Qt::WA_DeleteOnClose);
}

Method 2: Pass the Main Window Pointer to the Child (Simpler for Beginners)

If you want a more straightforward approach (with a bit more coupling between windows), you can pass the main window's pointer to the child window when you create it. Here's how:

Step 1: Update the Child Window's Header

Modify crediti.h to store a pointer to the main window:

#ifndef CREDITI_H
#define CREDITI_H

#include <QWidget>

// Forward declare MainWindow to avoid circular includes
class MainWindow;

namespace Ui {
class Crediti;
}

class Crediti : public QWidget
{
    Q_OBJECT

public:
    // Update constructor to accept the main window pointer
    explicit Crediti(MainWindow *mainWin, QWidget *parent = nullptr);
    ~Crediti();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Crediti *ui;
    MainWindow *m_mainWindow; // Store the main window pointer
};

#endif // CREDITI_H

Step 2: Initialize the Pointer in the Child Window's Constructor

Update crediti.cpp to save the main window pointer and use it in the button slot:

#include "crediti.h"
#include "ui_crediti.h"
#include "mainwindow.h" // Now we can include the main window header

Crediti::Crediti(MainWindow *mainWin, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Crediti),
    m_mainWindow(mainWin) // Initialize the main window pointer
{
    ui->setupUi(this);
}

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

void Crediti::on_pushButton_clicked()
{
    // Show the original main window
    m_mainWindow->show();
    // Close the child window
    this->close();
}

Step 3: Pass the Main Window Pointer When Creating the Child

Update your main window's button slot to pass this (the main window pointer) when creating the child:

void MainWindow::on_openCreditiBtn_clicked()
{
    // Pass the main window pointer to the child
    Crediti *creditiWindow = new Crediti(this);
    
    this->hide();
    creditiWindow->show();
    creditiWindow->setAttribute(Qt::WA_DeleteOnClose);
}

Both methods will fix your issue and let you return to the original main window when clicking the button in the child window. The first method (signals & slots) is more aligned with Qt's design principles, but the second is easier to wrap your head around as a beginner.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:12:40