回顾:
1.QT的编译
qmake使用
*.pro文件格式
2.QT的工具
帮助文档
配置工具
UI设计器
3.QT的类的使用
一.信号与槽
1.背景:
面向过程
模块之间低耦合设计(高内聚).
函数调用:
直接调用
回调调用
面向对象
模块之间低耦合设计(高内聚).
对象调用
直接调用
接口调用
QT:
信号与槽解决问题:
对象的成员变量的调用?
对象的成员函数的调用?
案例:
窗体,有一个文本框。
线程,每隔一秒改变文本框。
问题:
线程类访问窗体组件比较麻烦,需要传递。
在QT中,使用线程程序可能不工作。
2.使用信号与槽
最大的好处,不通过参数传递,直接调用对象。
以及在对象之间传递数据
2.1.头与实现必须分开。
2.2.必须继承QObject
2.3.被调用函数成为槽slot
2.4.调用函数成为信号
2.5.必须在类引入QObject中一个宏
2.6.实现与C++完全一样。
2.7.信号与槽的返回值必须是void
2.8.关联的信号与槽原型必须一致,名字可以不同
//log.h
#ifndef LOG_H
#define LOG_H
#include <QObject>
class Log : public QObject //定义槽函数必须继承QObject
{
Q_OBJECT
public slots:
void log(); //定义一个槽函数。槽函数是被调用的函数
};
#endif
//log.cpp
#include <log.h>
#include <iostream>
using namespace std;
void Log::log() //槽函数的实现
{
cout <<"call log!"<<endl;
}
//biz.h
#ifndef BIZ_H
#define BIZ_H
class BIz : public QObject
{
Q_OBJECT
public:
void biz(); //用这个函数调用siglog函数,siglog函数就是信号函数
public:
signals:
void siglog(); //定义信号函数。信号函数是调用槽函数的函数
}
#endif
//biz.cpp
#include <iostream>
#include <biz.h>
using namespace std;
void Biz :: biz() //实现biz函数,在函数中调用信号函数
{
sleep(1);
cout<<"tackle biziness!"<<endl;
emit siglog(); //信号函数的调用
}
//main.cpp
#include <biz.h>
#include <log.h>
int main()
{
Log log;
Biz biz;
QObject::connect( //连接信号与槽
&biz,
SIGNAL(siglog()),
&log,
SLOT(log())
)
biz.biz(); //调用biz
}
思考:
信号与槽在对象耦合上有什么优点?
3.QT可视化组件(控件)
其中的信号是怎么发出的?
信号是自动发出.
案例:
使用按钮的信号.
按钮事件发生的时候发出信号.
事件->信号->槽
信号与槽解决如下问题:事件发生的时候,怎么调用用户的函数?
新的类:
QMessageBox提供一组静态函数弹出对话框
步骤:
1.main.cpp
2.*.pro
3.对话框类
4.实现按钮clicked信号的对应槽函数
槽函数必须与clicked信号同型,
槽函数在哪个类定义?槽函数放入访问成员最多的类
5.绑定信号与槽
//mydialog.h
#ifndef MY_DIALOG_H
#define MY_DIALOG_H
#include <QDialog>
#include <QPushButton>
class MyDialog : public QDialog
{
Q_OBJECT
private:
QPushButton *btn;
public:
MyDialog(QWidget *parent=NULL);
~MyDialog();
public slots:
void showBox();
};
#endif
//mydialog.cpp
#include "mydialog.h"
#include <iostream>
#include <QMessageBox>
using std::cout;
MyDialog::MyDialog(QWidget*parent)
{
resize(400,300);
btn=new QPushButton(this);
btn->resize(100,30);
btn->move(150,150);
btn->setText("OK");
connect(btn,SIGNAL(clicked()),
this,SLOT(showBox()));
}
MyDialog::~MyDialog()
{
delete btn;
}
void MyDialog::showBox()
{
QMessageBox::information(this,"Information","this ismaomaochong!");
}
//main.cpp
#include <QApplication>
#include "mydialog.h"
int main(int s,char**v)
{
QApplication app(s,v);
MyDialog dlg;
dlg.setVisible(true);
return app.exec();
}
案例2:
加法器
1.设计界面(*.ui,*.h)
2.main.cpp
3.pro
4.对话框
5.处理信号与槽
设计好界面后,保存为frmdlg.ui文件。然后在终端对应文件夹下
uic frmdlg.ui -o frmdlg.h
生成界面的头文件。
//dlgjfq.h
#ifndef DLG_JFQ_H
#define DLG_JFQ_H
#include <QDialog>
#include "frmjfg.h"
class DlgJFQ : public QDialog
{
Q_OBJECT
private:
Ui_DlgJFQ *ui;
public:
DlgJFQ(QWidget *parent=NULL);
~DlgJFQ();
public slots:
void add();
};
#endif
//dlgjfq.cpp
#include "dlgjfq.h"
DlgJFQ::DlgJFQ(QWidget *parent)
{
ui=new Ui_DlgJFQ;
ui->setupUi(this);
connect(ui->btnAdd,SIGNAL(clicked()),
this,SLOT(add()));
}
DlgJFQ::~DlgJFQ()
{
delete ui;
}
void DlgJFQ::add()
{
//取字符串
QString strAdded=ui->txtAdded->text();
QString strAdd =ui->txtAdd ->text();
//转换为整数
int ia=strAdded.toInt();
int ib=strAdd.toInt();
//计算和
int ic=ia+ib;
//把和转换为文本显示到标签框
ui->lblResult->setText(QString::number(ic));
}
//main.cpp
#include <QApplication>
#include "dlgjfq.h"
int main(int args,char**argv)
{
QApplication app(args,argv);
DlgJFQ dlg;
dlg.show();
return app.exec();
}
//main.pro
TEMPLATE=app
SOURCES=main.cpp \
dlgjfq.cpp
HEADERS=frmjfg.h \
dlgjfq.h
CONFIG=release qt
QT=core gui
TARGET=main
二.QT类的继承结构
QT的类
core
数据集合
QString
几何类
QPoint
QSize
QRectangle
系统类
QColor
QFont
QImage
QIcon
QCursor
QBitmap
...
gui
窗体类
|-框架窗体 QMainWindow(SDI/MDI)[菜单/工具条/状态条/带文档与视图]
|-对话框窗体QDialog[模式对话框/非模式]
组件
显示组件
输入组件
按钮
容器
菜单
布局组件
高级数据组件
表格/树型
三.窗体类的结构
QObject QPaintDevice
|------|-------|
QWidget
|
|--------------------|------------------|
QMainWindow QDialog 控件
QObject:
非静态
connect
disconnect
静态
connect
disconnect
tr
维护子对象的关系
定时器事件
信号:
destroy.
QPaintDevice(所有可视化控件都是绘制设备)
可视化组件高度height() width();
屏幕分辨率等相关信息
QWidget
常规属性
几何属性:
图标
光标
标题
基本事件(绘制/鼠标事件/键盘事件)
作业:
1.阅读随机数程序.
注意:线程封装
信号与槽
2.写汇率计算器
3.思考:
信号与槽的使用特色与优点.