在QT中,我们时常会需要在主窗口里添加一些子窗口,比如添加一个新的对话框,或者在TabWidget中添加tab页面。通常添加子窗口后,如果在子窗口中做了一些操作,我们需要在主窗口中通过UI控件反映出来,但是由于ui对象是私有对象,所以一般的做法是使用QT中的信号槽机制,连接主窗口和子窗口对象,然后发送信号即可。
但是这种方法也有弊端,就是当我们在子窗口中有很多操作需要在主窗口中表现出来时,我们就需要建立很多的信号和槽,然后连接起来,可这样会很乱。可能过一段时间后再看这个程序,就忘记了这些信号和槽是做什么的,在哪连接的,让程序变的难以理解。所以,这里讲另一种方法,同样可以在子窗口中控制主窗口的UI控件。
效果
代码之路
这里使用的方法是传递主窗口的指针给子窗口,这样就可以使用这个指针调用主窗口类中的方法,主窗口类中方法中可以对ui控件进行操作。如果不是这种传指针的方法,而是直接new出主窗口的对象,即使调用了主窗口类的方法,在该方法中的对ui控件的操作也是没有效果的。
MainWindow.h
#include <QMainWindow>
#include "Dialog.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void UI_Open();
void UI_Close();
private slots:
void on_Btn_OpenDialog_clicked();
private:
Ui::MainWindow *ui;
Dialog *dlg_dialog;
};
#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);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_Btn_OpenDialog_clicked()
{
// 这里创建子窗口,并把父窗口的指针传给子窗口
dlg_dialog = new Dialog(this);
dlg_dialog->setModal(true);
dlg_dialog->show();
}
void MainWindow::UI_Open()
{
ui->Btn_Open->setEnabled(false);
ui->Btn_Close->setEnabled(true);
ui->statusbar->showMessage("开关已打开");
}
void MainWindow::UI_Close()
{
ui->Btn_Open->setEnabled(true);
ui->Btn_Close->setEnabled(false);
ui->statusbar->showMessage("开关已关闭");
}
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
// 两个类互相包含,在头文件中声明另一个类,在cpp文件中包含另一个类的头文件
class MainWindow;
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_Btn_Open_clicked();
void on_Btn_Close_clicked();
private:
Ui::Dialog *ui;
MainWindow *m_parent; // 主窗口类的对象
};
#endif // DIALOG_H
Dialog.cpp
#include "Dialog.h"
#include "ui_Dialog.h"
#include "MainWindow.h"
// 主窗口类传来的this指针,QWidget *类型
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
// 把传过来的父窗口类的指针强制类型转换
m_parent = static_cast<MainWindow*>(parent);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_Btn_Open_clicked()
{
ui->Btn_Open->setEnabled(false);
ui->Btn_Close->setEnabled(true);
m_parent->UI_Open();
}
void Dialog::on_Btn_Close_clicked()
{
ui->Btn_Open->setEnabled(true);
ui->Btn_Close->setEnabled(false);
m_parent->UI_Close();
}