回顾:
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 is maomaochong!"); }
//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.思考:
信号与槽的使用特色与优点.