zoukankan      html  css  js  c++  java
  • Qt界面编程:窗口传值方式

    1、问题

      一个这样的场景:主窗口界面有一个菜单项,点击该菜单项弹出一个对话框。点击对话框上的测试按钮,显示主窗口类中的一个字符串成员的内容。这就是整个窗口传值的需求描述。如何解决呢?首先想到的解决方法自然是使用Qt自带的signal/slot机制。即首先发信号给父窗口,父窗口接到信号执行槽函数发送一个携带所需数据的信号给子窗口。但是疑问来了:要在子窗口中接收到父窗口的信号必须进行signal和slot的绑定。这需要主窗口类的定义(1)。担心头文件的递归包含,我们只好再想另外一个方法。直接在子窗口中利用指向父窗口的指针来访问父窗口类的成员如何?但是,这显然也牵涉到了头文件的递归包含(2)。但,不试一试怎么知道?毕竟很多事情是无法用理论来解释的。

    2、尝试解决

    • 使用环境:Qt5.0,  Qt creator2.6, Windows XP sp3 32bit
    • 创建一个主窗口类和子窗口类,在主窗口类中声明一个QString类型的成员变量,访问权限设置为public(3),并在构造函数中进行初始化
    • 在子窗口增加一个QLabel组件,用于显示父窗口的成员变量的内容。
    • 在父类中调用子类弹出子窗口时,要给子窗口的构造函数传递this指针,以设置子窗口的父窗口。因为子窗口的构造函数带一个默认值0,也即是没有设置父窗口的。

    3、代码

     1 //主窗口的.h文件,头文件和预处理机制已经去掉
     2 class MainWindow : public QMainWindow
     3 {
     4     Q_OBJECT
     5     
     6 public:
     7     explicit MainWindow(QWidget *parent = 0);
     8     ~MainWindow();
     9     
    10 private slots:
    11     void on_actionPopup_triggered();
    12 
    13 private:
    14     Ui::MainWindow *ui;
    15     QString name;    //declaration
    16 };
    17 //主窗口的cpp实现文件,其他同上
    18 MainWindow::MainWindow(QWidget *parent) :
    19     QMainWindow(parent),
    20     ui(new Ui::MainWindow)
    21 {
    22     ui->setupUi(this);
    23     name = "YES";   //initialization of member variable
    24 }
    25 
    26 MainWindow::~MainWindow()
    27 {
    28     delete ui;
    29 }
    30 
    31 void MainWindow::on_actionPopup_triggered()
    32 {
    33     Dialog myDlg(this);   //This is important
    34     myDlg.exec();
    35 }
    36 //Dialog header
    37 namespace Ui {
    38 class Dialog;
    39 }
    40 
    41 class Dialog : public QDialog
    42 {
    43     Q_OBJECT
    44     
    45 public:
    46     explicit Dialog(QWidget *parent = 0);
    47     ~Dialog();
    48     
    49 private slots:
    50     void on_pushButton_test_clicked();
    51 
    52 private:
    53     Ui::Dialog *ui;
    54 };
    55 //dialog implementation
    56 Dialog::Dialog(QWidget *parent) :
    57     QDialog(parent),
    58     ui(new Ui::Dialog)
    59 {
    60     ui->setupUi(this);
    61 }
    62 
    63 Dialog::~Dialog()
    64 {
    65     delete ui;
    66 }
    67 
    68 void Dialog::on_pushButton_test_clicked()
    69 {
    70     MainWindow* ptr = (MainWindow*)parentWidget();  //conversion
    71     ui->label->setText(ptr->name);
    72 }

    4、解释
      注意上面的指针转换,MainWindow* ptr = (MainWindow*)parentWidget();,这句话首先调用parentWidget()获得子窗口的父窗口指针,其类型为QWidget类型,故此需要强制转换为MainWindow类型。所以在子窗口的头文件的中必须要包含主窗口的头文件,否则连编译都无法通过。其次是在父窗口中调用的方式:    DialogmyDlg(this); myDlg.exec();必须要传递this指针给子窗口的构造函数进行初始化。否则,parentWidget()将无法取得父窗口的指针。

    5、新问题

    1. 头文件包含问题(上面1,2所标示)。在父窗口的头文件中,包含了子窗口的头文件。这原本没有问题。但是在子窗口中又再次包含了父窗口的头文件,这一样一来彼此包含,你中有我我中有你,生生不息了。为什么能这样工作呢?是不是头文件的预编译机制突破了这一限制?
    2. 上面3所标识的问题,其实并没有严格的要求,至少在Qt Creator中没有这样的限制。你可以将该成员变量设置为private,protected, public的,但是在子窗口中照样能访问。虽然按照C++的设计原则来说,数据应该是类的私有部分。这到底是为什么呢?

    作者:24K纯开源
    Email: zhangzhongke007@163.com
    出处:http://www.cnblogs.com/csuftzzk/
    本文版权归24K纯开源和博客园共同拥有,欢迎转载,但未经作者同意必须保留此声明,且在文章明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    单相、二相、三相区别
    Live for Speed 车模、赛道模型导出
    Lenovo/IBM Thinkpad X41 Tablet
    科普题外话 赛车性能的关键指标: 马力和扭力
    MAME™ Official Developer Documentation!
    Visual Studio 2005 & SQL Server 2005 are COMING!
    星际争霸(Star Craft)的Sprites导出
    推荐一本关于操作系统实践的好书
    科普题外话:Experimental Advanced Superconducting Tokamak - 人造太阳
    The Space Elevator -通往地球同步轨道的天梯
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/3077954.html
Copyright © 2011-2022 走看看