Qt中子窗口访问父窗口的成员变量

这里说的父窗口成员变量指的是含有自定义类型的变量,比如包含自定义结构/类的容器类(如QVector),对于父窗口中int、string等常规成员,可通过直接传地址的办法进行访问,不复杂。


例:父窗口(MainWindow)类中有成员变量QVector<TypeA> vect,TypeA是MainWindow中定义的结构体。

子窗口(Dialog1)需要访问vect中的元素。

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "ui_mainwindow.h"
#include <QVector>

class MainWindow : public QMainWindow, private Ui::MainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    struct TypeA{
        int id;
        QString name;
    };

private:
    void addItem(int id, QString name);
    QVector<TypeA> vect;

private slots:
    void on_viewDialog_clicked();
};

#endif // MAINWINDOW_H


//mainwindow.cpp
#include "mainwindow.h"
#include "dialog1.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi(this);
    addItem(100, "Tom");
    addItem(101, "Jerry");
    addItem(102, "Jack");
}

void MainWindow::addItem(int id, QString name)
{
    TypeA item;
    item.id = id;
    item.name = name;
    vect.push_back(item);
}

void MainWindow::on_viewDialog_clicked()
{
    Dialog1 *newDlg = new Dialog1(this);
    newDlg->updateTable();        //方法1&方法3
    //newDlg->updateTable(vect);    //方法2
    newDlg->show();
    newDlg->raise();
    newDlg->activateWindow();
}

方法1:

在Dialog1中获取父窗口指针,通过指针直接访问成员vect,问题在于这时候vect需要设置为public才可访问。(类Dialog1没有继承类MainWindow)

//方法1
void Dialog1::updateTable()
{
    MainWindow * p = (MainWindow*) parentWidget();  //获取父窗口指针

    int vSize = p->vect.size();
    for (int i = 0; i < vSize; i++){
        tableWidget->insertRow(i);
        tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(p->vect[i].id)));
        tableWidget->setItem(i, 1, new QTableWidgetItem(p->vect[i].name));
    }
}

方法2:

通过传引用的方法在Dialog1中访问vect(如果不需要修改可传const引用)。这种情况下Dialog1中的updateTable函数需要加参数,对于mainwindow.h的include需要写在dialog1.h中,注意不要在dialog1.h中包含mainwindow.h的同时又在后者包含前者,会造成重复包含的问题

此时在Mainwindow中,vect不必是public属性的,可以是private。

//方法2
void Dialog1::updateTable(const QVector<MainWindow::TypeA> &vect)
{
    int vSize = vect.size();
    for (int i = 0; i < vSize; i++){
        tableWidget->insertRow(i);
        tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(vect[i].id)));
        tableWidget->setItem(i, 1, new QTableWidgetItem(vect[i].name));
    }
}

方法3:

在MainWindow中增加一个public的成员函数来获取vect的指针,在Dialog1中调用此函数获取vect指针,再在Dialog1中进行操作。注意此时Dialog1中得到的不是引用而是指针,访问成员使用"->"而不是"."。

这种方法较好地实现了封装,将vect设为private可以防止不必要的访问。


    //mainwindow.h中添加public成员函数
    QVector<TypeA>* getVect(){return &vect;}

//方法3
void Dialog1::updateTable()
{
    MainWindow * p = (MainWindow*) parentWidget();  //获取父窗口指针
    QVector<MainWindow::TypeA> *vect = p->getVect();    //获取指向vect的指针

    int vSize = vect->size();
    for (int i = 0; i < vSize; i++){
        tableWidget->insertRow(i);
        tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(vect->at(i).id)));
        tableWidget->setItem(i, 1, new QTableWidgetItem(vect->at(i).name));
    }
}


PS:方法1、3的时候注意创建Dialog1实例的时候将父窗口的指针传入。


第一次在CSDN发文,旨在与大家多多交流共同进步,代码如有不足之处,欢迎大家多多提意见!




  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值