Qt中子窗体控件向父窗体控件传值

今天学习Qt中控件相互传值的方法。其中参考了一些网上的意见。今天学习了两种方法。其中一种是利用全局变量;另一种是利用了Qt中的信号和槽机制。当学习signals和slot机制的时候,有一些疑问,在介绍利用signals和slot进行值传递的时候,再说。

练习是这样子,如下两图所示。
第一幅图是主窗体,在画笔宽度文本框和画笔颜色文本框中可以填入宽度和样色值,决定画笔宽度和颜色,然后选择右边的画椭圆,画矩形,画多边形按钮可以画相应的图形,其中画图中,大部分功能是直接在函数中赋值好的,可以创建固定大小的图形。
但是,练习中实现了一个功能,可以改变其中的一个坐标,通过文本框来改变。
也可以单击坐标点按钮,会弹出一个子窗体对话框,如第二个图所示,练习中只实现了X文本框向父窗体传值,其他三个没有实现,以后吧。当在X文本框填入X值后,单击确定按钮,它的值将传向父窗体中未命名的四个文本框的左上角那个,同时显示出来,这时再按画椭圆,画矩形按钮,其中一个坐标将改变,图形也会改变,练习中是改变的宽度值。
Qt中子窗体控件向父窗体控件传值_第1张图片

Qt中子窗体控件向父窗体控件传值_第2张图片

下面是主要代码:
首先建立一个工程,创建父窗体,结果如上“简单图形绘制”,然后给坐标点按钮和其他三个按钮添加槽函数,下面是代码,利用全局变量和signals/slot来进行传值。测试的时候可以注释掉其中一种,看看两种是不是都可以。
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots://槽函数
    void on_CreateEllipse_clicked();//画椭圆

    void on_createRect_clicked();//画矩形

    void on_createPloygen_clicked();//画多边形

    void on_pushButton_clicked();//坐标点槽函数
    void receivedata(QString mx);//接收数据槽
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include"ellipse.h"

extern QString sx;//声明的全局变量



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{


    ui->setupUi(this);

    //Ellipse *els   = new Ellipse;
    //connect(els,SIGNAL(senddata(QString )),this,SLOT(receivedata(QString )));
    //connect(els,els->senddata,this,this->receivedata);
    //els->show();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_CreateEllipse_clicked()//画椭圆
{

    QString pw;
    QString pc;
    pw = ui->penWidth->text();//画笔宽度字符串
    pc = ui->penColor->text();//画笔颜色字符串
    int w;
    int c;
    w = pw.toInt();//画笔宽度转为整型
    c = pc.toInt();//画笔颜色转为整型


QString esx;
esx = sx;
int e;
e = esx.toInt();//从子窗体中接收到的控件变量有QString转为Int
    QPen pen;//画笔
    pen.setStyle(Qt::DashDotLine);
    pen.setWidth(w);//设置画笔宽度

    if(c == 7)//颜色可以参考16色值,这里文本框中为7 颜色为红,不填默认为黑,测试而已
    {
         pen.setBrush(Qt::red);//画笔设为红色
    }




    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);

    QGraphicsScene *scene = new QGraphicsScene;

    scene->addEllipse(150,150,e,200,pen);//画椭圆,这里动态传人了宽度值,为e,是从子窗体中接收的


    ui->graphicsView->setScene(scene);



}

void MainWindow::on_createRect_clicked()//画矩形
{
    QString pw;
    QString pc;
    pw = ui->penWidth->text();
    pc = ui->penColor->text();
    int w;
    int c;
    w = pw.toInt();
    c = pc.toInt();


    QPen pen;
    pen.setStyle(Qt::DashDotLine);
    pen.setWidth(w);

    if(c == 7)
    {
         pen.setBrush(Qt::red);
    }

    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);



    int rc;
    rc = ui->x->text().toInt();
    QGraphicsScene *scene = new QGraphicsScene;
     scene->addRect(100,200,rc,120,pen);//画矩形,这里也动态的传人了宽度值,为e,接收自子窗体。
      ui->graphicsView->setScene(scene);
}

void MainWindow::on_createPloygen_clicked()//画多边形
{
    QString pw;
    QString pc;
    pw = ui->penWidth->text();
    pc = ui->penColor->text();
    int w;
    int c;
    w = pw.toInt();
    c = pc.toInt();


    QPen pen;
    pen.setStyle(Qt::DashDotLine);
    pen.setWidth(w);

    if(c == 7)
    {
         pen.setBrush(Qt::red);
    }

    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);

    QGraphicsScene *scene = new QGraphicsScene;
    QPolygon polygon;
       polygon << QPoint(20, 20);
       polygon << QPoint(122, 25);
       polygon << QPoint(130, 120);
       polygon << QPoint(140, 150);
       polygon << QPoint(20, 110);
       polygon << QPoint(0, 50);
    scene->addPolygon(polygon,pen);//画多边形
     ui->graphicsView->setScene(scene);

}

void MainWindow::on_pushButton_clicked()//坐标点按钮槽,单击显示选择坐标对话框
{
    Ellipse *els = new Ellipse(this);//构建Ellipse对话框对象
   // Ellipse *els   = new Ellipse;
   connect(els,SIGNAL(senddata(QString )),this,SLOT(receivedata(QString )));//信号链接

    els->show();//显示对话框

}

void MainWindow::receivedata(QString )//接收槽
{
   ui->x->setText(sx);//显示出接收的值
}

子窗体代码和头文件:
ellipse.h

#ifndef ELLIPSE_H
#define ELLIPSE_H

#include 
#include
namespace Ui {
class Ellipse;
}

class Ellipse : public QMainWindow
{
    Q_OBJECT

public:
    explicit Ellipse(QWidget *parent = 0);
    ~Ellipse();

 signals:
    void senddata(QString );//信号,用来向父窗体传值

private slots:
    void on_pushButton_clicked();//确定按钮槽

private:
    Ui::Ellipse *ui;


};

#endif // ELLIPSE_H

ellipse.cpp

#include "ellipse.h"
#include "ui_ellipse.h"


QString sx;//全局变量,这是利用全局变量进行传值


Ellipse::Ellipse(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Ellipse)
{
    ui->setupUi(this);
}

Ellipse::~Ellipse()
{
    delete ui;
}



void Ellipse::on_pushButton_clicked()//确定按钮槽
{
    emit senddata(ui->Xedit->text());//发送信号
    sx = ui->Xedit->text();//全局变量值
    qDebug()<<"danji"<//这个是测试用的,可以去掉

}

觉得利用全局变量进行传值还是好理解,也是比较好实现的,只要在两个类中分别声明全局变量就可以了。
先在父窗体中声明一个全局变量: QString extern sx;
然后再在子窗体Ellipse中声明全局变量 QString sx;这样子在子窗体中对全局变量sx的改变就会反应到父窗体中了。

重点说一下利用signals/slot进行值传递实现和个人一些疑问。
把需要的代码重新复制过来了。
1.

#ifndef ELLIPSE_H
#define ELLIPSE_H

#include 
#include
namespace Ui {
class Ellipse;
}

class Ellipse : public QMainWindow
{
    Q_OBJECT

public:
    explicit Ellipse(QWidget *parent = 0);
    ~Ellipse();

 signals:
    void senddata(QString );//信号,用来向父窗体传值

private slots:
    void on_pushButton_clicked();//确定按钮槽

private:
    Ui::Ellipse *ui;


};

#endif // ELLIPSE_H

上面注释的地方,分别声明了信号和槽。信号和槽是关联的,就是说,当确定按钮单击以后,就会发送信号senddata(QString);这个信号是向父窗体传值的,把X文本框中字符串传给父窗体。这里还好理解。
2.

void Ellipse::on_pushButton_clicked()//确定按钮槽
{
    emit senddata(ui->Xedit->text());//发送信号
    sx = ui->Xedit->text();//全局变量值
    qDebug()<<"danji"<<sx;//这个是测试用的,可以去掉

}

如注释,这个简单,就是一单击按钮,发送一个信号,信号的接收者在父窗体中,个人的主要疑问也在父窗体中。

下面是父窗体的解释和自己的疑问.
3.

void receivedata(QString mx);//接收数据槽

上面是一个简单的接收子窗体传过来的值得槽函数。
4.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{


    ui->setupUi(this);

    //Ellipse *els   = new Ellipse;  ---------@1
    //connect(els,SIGNAL(senddata(QString )),this,SLOT(receivedata(QString )));-----@2
    //els->show();----@3
}

这里问题是如果我想向平时练习一样只写上@2 一句,想实现信号接收,结果是根本没有反应,如果加上@1 @2 @3,就又构造另一个对话框,也可以实现信号接收,但是单击坐标点弹出来的那个一样的对话框却不行。如果只在这里写上@1 一句为什么弹出的对话框不能接收。
5.

void MainWindow::on_pushButton_clicked()//坐标点按钮槽,单击显示选择坐标对话框
{
    Ellipse *els = new Ellipse(this);//构建Ellipse对话框对象------@4
   // Ellipse *els   = new Ellipse;-------@5
   connect(els,SIGNAL(senddata(QString )),this,SLOT(receivedata(QString )));//信号链接-@6

    els->show();//显示对话框--------@7

}

接着上面的问题,@4和@5 有什么区别么?如果把上面的@1,@2,@3都去掉,就完全可以实现想要的功能。
如果把这里的@6注释掉,在上一步中只保留@2,信号是一样的,可是不行。不知道为什么?

你可能感兴趣的:(Qt,C/C++)