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


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

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

[cpp]  view plain  copy
  1. //mainwindow.h  
  2. #ifndef MAINWINDOW_H  
  3. #define MAINWINDOW_H  
  4.   
  5. #include "ui_mainwindow.h"  
  6. #include <QVector>  
  7.   
  8. class MainWindow : public QMainWindow, private Ui::MainWindow  
  9. {  
  10.     Q_OBJECT  
  11.       
  12. public:  
  13.     explicit MainWindow(QWidget *parent = 0);  
  14.     struct TypeA{  
  15.         int id;  
  16.         QString name;  
  17.     };  
  18.   
  19. private:  
  20.     void addItem(int id, QString name);  
  21.     QVector<TypeA> vect;  
  22.   
  23. private slots:  
  24.     void on_viewDialog_clicked();  
  25. };  
  26.   
  27. #endif // MAINWINDOW_H  


[cpp]  view plain  copy
  1. //mainwindow.cpp  
  2. #include "mainwindow.h"  
  3. #include "dialog1.h"  
  4.   
  5. MainWindow::MainWindow(QWidget *parent) :  
  6.     QMainWindow(parent)  
  7. {  
  8.     setupUi(this);  
  9.     addItem(100, "Tom");  
  10.     addItem(101, "Jerry");  
  11.     addItem(102, "Jack");  
  12. }  
  13.   
  14. void MainWindow::addItem(int id, QString name)  
  15. {  
  16.     TypeA item;  
  17.     item.id = id;  
  18.     item.name = name;  
  19.     vect.push_back(item);  
  20. }  
  21.   
  22. void MainWindow::on_viewDialog_clicked()  
  23. {  
  24.     Dialog1 *newDlg = new Dialog1(this);  
  25.     newDlg->updateTable();        //方法1&方法3  
  26.     //newDlg->updateTable(vect);    //方法2  
  27.     newDlg->show();  
  28.     newDlg->raise();  
  29.     newDlg->activateWindow();  
  30. }  

方法1:

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

[cpp]  view plain  copy
  1. //方法1  
  2. void Dialog1::updateTable()  
  3. {  
  4.     MainWindow * p = (MainWindow*) parentWidget();  //获取父窗口指针  
  5.   
  6.     int vSize = p->vect.size();  
  7.     for (int i = 0; i < vSize; i++){  
  8.         tableWidget->insertRow(i);  
  9.         tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(p->vect[i].id)));  
  10.         tableWidget->setItem(i, 1, new QTableWidgetItem(p->vect[i].name));  
  11.     }  
  12. }  

方法2:

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

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

[cpp]  view plain  copy
  1. //方法2  
  2. void Dialog1::updateTable(const QVector<MainWindow::TypeA> &vect)  
  3. {  
  4.     int vSize = vect.size();  
  5.     for (int i = 0; i < vSize; i++){  
  6.         tableWidget->insertRow(i);  
  7.         tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(vect[i].id)));  
  8.         tableWidget->setItem(i, 1, new QTableWidgetItem(vect[i].name));  
  9.     }  
  10. }  

方法3:

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

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


[cpp]  view plain  copy
  1. //mainwindow.h中添加public成员函数  
  2. QVector<TypeA>* getVect(){return &vect;}  

[cpp]  view plain  copy
  1. //方法3  
  2. void Dialog1::updateTable()  
  3. {  
  4.     MainWindow * p = (MainWindow*) parentWidget();  //获取父窗口指针  
  5.     QVector<MainWindow::TypeA> *vect = p->getVect();    //获取指向vect的指针  
  6.   
  7.     int vSize = vect->size();  
  8.     for (int i = 0; i < vSize; i++){  
  9.         tableWidget->insertRow(i);  
  10.         tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(vect->at(i).id)));  
  11.         tableWidget->setItem(i, 1, new QTableWidgetItem(vect->at(i).name));  
  12.     }  
  13. }  


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


转自:http://blog.csdn.net/marvel90/article/details/8852680
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐