您的位置:首页 > 编程语言 > Qt开发

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

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

练习是这样子,如下两图所示。

第一幅图是主窗体,在画笔宽度文本框和画笔颜色文本框中可以填入宽度和样色值,决定画笔宽度和颜色,然后选择右边的画椭圆,画矩形,画多边形按钮可以画相应的图形,其中画图中,大部分功能是直接在函数中赋值好的,可以创建固定大小的图形。

但是,练习中实现了一个功能,可以改变其中的一个坐标,通过文本框来改变。

也可以单击坐标点按钮,会弹出一个子窗体对话框,如第二个图所示,练习中只实现了X文本框向父窗体传值,其他三个没有实现,以后吧。当在X文本框填入X值后,单击确定按钮,它的值将传向父窗体中未命名的四个文本框的左上角那个,同时显示出来,这时再按画椭圆,画矩形按钮,其中一个坐标将改变,图形也会改变,练习中是改变的宽度值。





下面是主要代码:

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

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

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<QGraphicsScene>
#include<QGraphicsView>
#include<QString>
#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 <QMainWindow>
#include<QDebug>
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"<<sx;//这个是测试用的,可以去掉

}


觉得利用全局变量进行传值还是好理解,也是比较好实现的,只要在两个类中分别声明全局变量就可以了。

先在父窗体中声明一个全局变量: QString extern sx;

然后再在子窗体Ellipse中声明全局变量 QString sx;这样子在子窗体中对全局变量sx的改变就会反应到父窗体中了。

重点说一下利用signals/slot进行值传递实现和个人一些疑问。

把需要的代码重新复制过来了。

1.

#ifndef ELLIPSE_H
#define ELLIPSE_H

#include <QMainWindow>
#include<QDebug>
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,信号是一样的,可是不行。不知道为什么?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  传值 方法 控件 窗体