当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 7 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2015-12-15 12:31 

注册: 2010-10-31 9:15
帖子: 507
系统: kubuntu 16.04
送出感谢: 0 次
接收感谢: 13
新工程文件有如下5个文件:
mainwindow.h (主窗口类)
stat.h (子窗口类)
main.cpp (显示窗口,只有2行代码)
mainwindow.cpp(定义主窗口及控件,生成子窗口)
stat.cpp (定义子窗口及控件)



其中main.cpp最简单,就是创建并显示主窗口。
代码:
#include <QApplication>
#include "mainwindow.h"
int main(int argc , char **argv)
{
    QApplication app(argc,argv);
    MainWindow *w = new MainWindow ;
    w->show();
    return app.exec();
}



在mainwindow.h里声明了一个主窗口要用到的控件。
代码:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>  //为了简洁明了直接上QtGui头文件,它包含所需要的一切相关类。
class MainWindow : public QMainWindow
{
    Q_OBJECT
private slots:
    void gen1();  //此函数是当用户点击主菜单里的项时,生成子窗口。
public:
    QSpinBox *spinbox ; 
    //非相关的代码,如窗口布局等全部省略。
};
#endif // MAINWINDOW_H



在stat.h里声明子窗口,点击button后就可以刷新spinbox里的值了。
代码:
#include "mainwindow.h"
#include <QtGui>
class genB1Dialog : public QDialog
{
    Q_OBJECT
public:
    genB1Dialog(QWidget *parent = 0);
    void hookMainWindow(MainWindow *w) ;  //创建一个函数,其参数是窗口指针
    MainWindow *p ;                       //创建一个窗口指针
private:
    QSpinBox *spinbox ;
    QPushButton *button ;
signals:
    void ToMainWindow( int );
private slots:
    void monitor() ;  //子窗口里的按钮点击后信号发送给此槽函数,然后函数内实现子窗口里的spinbox和主窗口里的spinbox数据同步
    void updateToMainWindow_Spinbox(int) ;
};



在MainWindow.cpp中的代码是界面布局和生成子窗口。
代码:
#include <QtGui>
#include "mainwindow.h"
#include "stat.h"
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
   //以下非相关的代码全部用//给注释掉了,只需记得主窗口里有一个QSpinbox,初使值为5
    //createAct();
    //createMenus();
    //textEdit = new QTextEdit ;
    spinbox = new QSpinBox ;
    spinbox->setValue(5);
    //QSplitter *main = new QSplitter(Qt::Vertical);
    //main->addWidget(top);
   // main->addWidget(bottom);
    //setCentralWidget(main);
}
void MainWindow::gen1()
{
    genF1Dialog *dlg = new genF1Dialog(this) ;  //当点击主窗口菜单File下的creator项时,生成此子窗口,

    ......
    //以上省略你要实现的代码,最关键的是下一行代码,把主窗口指针this通过hookMainWindow传给了dlg子窗口
    dlg->hookMainWindow(this);
   
    QObject::connect(dlg , SIGNAL(ToMainTable(int)) , this , SLOT(updateToMainWindow_Spinbox(int)) ;
    dlg->show();
}
void MainWindow::updateToMainWindow_Spinbox(int a)
{
    spinbox->setValue( a ) ;
}



在stat.cpp里是子窗口类的定义
代码:
#include <QDialog>
#include "stat.h"
genF1Dialog::genF1Dialog(QWidget *parent) : QDialog(parent)
{
   //以下非相关的代码全部用//给注释掉
    spinbox = new QSpinBox(this) ;
    spinbox->setValue(0);
    button = new QPushButton("Update") ;
 
    //QVBoxLayout *mainLayout = new QVBoxLayout ;
    //mainLayout->addWidget(table);
    //mainLayout->addWidget(spinbox);
    //setLayout(mainLayout);
    QObject::connect(button , SIGNAL(clicked()) , this , SLOT(monitor()) ) ; //创建按钮点击信号,并与函数monitor关联。
   // resize(800,600);
}
void genF1Dialog::hookMainWindow(MainWindow *w)
{
    p = w ;  //让指针p指向主窗口

}
void genFDialog::monitor()
{
    spinbox->setValue( p->spinbox->value() ) ;  //把主窗口spinbox的数据传到此子窗口的spinbox里
}



最关键的是在void MainWindow::gen1()函数里用语句genF1Dialog *dlg = new genF1Dialog(this)生成子窗口后,再用语句dlg->hookMainWindow(this)把主窗口指针引给dlg子窗口。子窗口头文件stat.h里声明一个窗口指针MainWindow *p ,让它通过 stat.cpp里的void genF1Dialog::hookMainWindow(MainWindow *w)函数把主窗口指针赋给它。这时终于可以在dlg子窗口里通过指针p访问主窗口里的控件了。

反过来,如果我要把子窗口里spinbox的值传给主窗口呢?
那就简单一些了,只要在stat.h里定义一个信号:
signals:
void ToMainWindow( int ); //因为spinbox里的值是一个int型,所以信号里的参数也是int型。
即可。
在你想要传给主窗口的时候用语句:
emit ToMainWindow( spinbox->value() ) ;

发射了信号,接下来就要接收信号了,在mainwindow.cpp文件的void MainWindow::gen1()函数里添加语句:
QObject::connect(dlg , SIGNAL(ToMainTable(int)) , this , SLOT(updateToMainWindow_Spinbox(int)) ;

当然,updateToMainWindow_Spinbox(int)也要在mainwindow.h中声明一下。
最后在mainwindow.cpp中添加如下语句:
void MainWindow::updateToMainWindow_Spinbox(int a)
{
spinbox->setValue( a ) ; //把子窗口spinbox的数据传到主窗口的spinbox里
}


到这里工程就可以完工了。实现了双向通信。小小例子,浪费了我2个小时,希望能帮到有需要又没头绪的初学者。
[/code]


_________________
百度网盘 2048G容量 大放送!
百度网盘资源论坛一键保存资源!


最后由 flwwater 编辑于 2015-12-15 18:41,总共编辑了 1 次

页首
 用户资料  
 
2 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2015-12-15 14:28 
头像

注册: 2010-10-07 14:23
帖子: 33999
地址: 某系某星某洲某国某省某市
系统: Archdows10
送出感谢: 29
接收感谢: 151
:em11 :em11


_________________
心似浮云常自在,意如流水任东西。
此事背后一定有个天大的咪咪
广告:
1、走过路过,不要错过,dropbox网盘2.25G大放送
py大法好,退C保平安
java多妖孽,VB本异端
日诵一千遍,快活似神仙


页首
 用户资料  
 
3 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2015-12-15 15:45 
头像

注册: 2008-09-18 13:11
帖子: 2797
送出感谢: 1
接收感谢: 458
代码:
genF1Dialog *dlg = new genF1Dialog(this);

这里已经把this传给子窗口了,何必后面再传一次


页首
 用户资料  
 
4 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2015-12-16 13:49 
头像

注册: 2006-03-14 10:25
帖子: 647
送出感谢: 1
接收感谢: 5
mark :Music


页首
 用户资料  
 
5 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2015-12-20 12:13 

注册: 2010-10-31 9:15
帖子: 507
系统: kubuntu 16.04
送出感谢: 0 次
接收感谢: 13
astolia 写道:
代码:
genF1Dialog *dlg = new genF1Dialog(this);

这里已经把this传给子窗口了,何必后面再传一次


正所谓条条道路通罗马,既然有朋友提出了建议,那么给出第二种解法:
在stat.h里:
class genF1Dialog : public QDialog
{
Q_OBJECT
public:
genF1Dialog(MainWindow *parent); //直接把主窗口指针传过来,不再初使化为0.
//void hookMainWindow(MainWindow *w) ; //所以这个就不需要了
MainWindow *p ; //创建一个窗口指针

//.....其余代码都一样
};

在stat.cpp里:
genF1Dialog::genF1Dialog(MainWindow *parent) : QDialog(parent)
{
p = parent ; //指针直接赋值,指向主窗口
}
void genFDialog::monitor()
{
spinbox->setValue( p->spinbox->value() ) ; //此处无需更改,p同样有效。
}


_________________
百度网盘 2048G容量 大放送!
百度网盘资源论坛一键保存资源!


页首
 用户资料  
 
6 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2016-01-13 10:41 

注册: 2016-01-13 10:35
帖子: 1
系统: Windows10/ubuntu15.1
送出感谢: 0 次
接收感谢: 0 次
虽然说Dialog可以有父控件且子控件持有父控件的指针不会有空间性能上的问题,不过总感觉这种方式并不“优雅”。觉得在子控件里按键时发出带有spinbox值的信号,在父控件里连接这个自定义的信号,再改变父控件的spinbox的值,这样控件的控制权的管理会清晰些。


页首
 用户资料  
 
7 楼 
 文章标题 : Re: Qt/C++ 子窗口和主窗口通信技术简解(献给初学者)
帖子发表于 : 2016-12-10 13:47 

注册: 2010-10-31 9:15
帖子: 507
系统: kubuntu 16.04
送出感谢: 0 次
接收感谢: 13
谢谢两位大神的建议 :Haha


_________________
百度网盘 2048G容量 大放送!
百度网盘资源论坛一键保存资源!


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 7 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 1 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译