信号与槽

来源:互联网 发布:淘宝手机兼职怎么做 编辑:程序博客网 时间:2024/05/19 23:58
回顾:
1.QT的编译
qmake使用
*.pro文件格式
2.QT的工具
帮助文档
配置工具
UI设计器
3.QT的类的使用


一.信号与槽
1.背景:
面向过程
模块之间低耦合设计(高内聚).
函数调用:
直接调用
回调调用
面向对象
模块之间低耦合设计(高内聚).
对象调用
直接调用
接口调用
QT:
信号与槽解决问题:
对象的成员变量的调用?
对象的成员函数的调用?
案例:
窗体,有一个文本框。

线程,每隔一秒改变文本框。

通过参数传递的问题:
线程类访问窗体组件比较麻烦,需要传递。

在QT中,使用线程程序可能不工作。

以下用信号与槽的方式

shthread.h

#ifndef SHAKE_THREAD_H#define SHAKE_THREAD_H#include <pthread.h>#include <QLineEdit>class ShakeThread : public QObject {Q_OBJECTprivate:pthread_t tid;static void *s_run(void *);public:ShakeThread();virtual void run();void start();public:signals:void setNumber(QString);};#endif

shthread.cpp

#include "shthread.h"#include <unistd.h>#include <math.h>#include <stdio.h>ShakeThread::ShakeThread(){}void *ShakeThread::s_run(void * d){ShakeThread *st=(ShakeThread*)d;st->run();return NULL;}void ShakeThread::start(){pthread_create(&tid,0,s_run,this);}void ShakeThread::run(){//实现线程逻辑int num;while(1){num=rand()%10000000;//修改文本emit setNumber(QString::number(num));usleep(10000);}}

shake.h

#ifndef SHAKE_H#define SHAKE_H#include <QDialog>#include <QLineEdit>#include "shthread.h"class ShakeForm : public QDialog{Q_OBJECTprivate:QLineEdit *txt;ShakeThread  *th;public:ShakeForm(QWidget*parent=NULL);~ShakeForm();};#endif

shake.cpp

#include "shake.h"ShakeForm::ShakeForm(QWidget*parent){txt=new QLineEdit(this);resize(400,300);txt->resize(100,30);txt->move(10,10);th=new ShakeThread();connect(th,SIGNAL(setNumber(QString)),txt,SLOT(setText(QString)));th->start();}ShakeForm::~ShakeForm(){delete txt;}

main.cpp

#include <QApplication>#include "shake.h"main(int s,char**v){QApplication  app(s,v);ShakeForm dlg;dlg.setVisible(true);return app.exec();}


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/*1*/{Q_OBJECT/*2*/public slots:/*3*/void log(int);};/*4*/#endif
log.cpp

#include "log.h"#include <iostream>using namespace std;void Log::log(int s){cout<<"日志调用!"<<s<<"\n"<<endl;}
biz.h

#ifndef BIZ_H#define BIZ_H#include <QObject>class Biz : public QObject/*1*/{Q_OBJECT/*2*/public:void biz();public :signals:void siglog(int);//信号函数不需要实现};#endif
biz.cpp

#include "biz.h"#include <iostream>#include <unistd.h>using namespace std;void Biz::biz(){while(1){sleep(1);cout<<"业务处理!\n";//怎么调用槽?emit siglog(99999);/*4*/}}
main.cpp

#include "biz.h"#include "log.h"int main(){Log log;Biz biz;QObject::connect(&biz,//信号源对象SIGNAL(siglog(int)),//信号函数&log,//槽目标对象SLOT(log(int)));//槽函数biz.biz();}
main.pro

TEMPLATE=appSOURCES=main.cpp\biz.cpp\log.cppHEADERS=log.h\biz.hCONFIG=release qtQT=coreTARGET=main


思考:
信号与槽在对象耦合上有什么优点?

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_OBJECTprivate:QPushButton *btn;public:MyDialog(QWidget *parent=NULL);~MyDialog();publicslots: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(); }

main.pro

TEMPLATE=appSOURCES=main.cpp\mydialog.cppHEADERS=mydialog.hCONFIG=release qtQT=core guiTARGET=main



案例2:
加法器
1.设计界面(*.ui,*.h)
2.main.cpp
3.pro
4.对话框
5.处理信号与槽

界面

ffrmjfq.h

/********************************************************************************** Form generated from reading ui file 'frmjfq.ui'**** Created: Mon Nov 22 15:32:53 2010**      by: Qt User Interface Compiler version 4.4.3**** WARNING! All changes made in this file will be lost when recompiling ui file!********************************************************************************/#ifndef FRMJFG_H#define FRMJFG_H#include <QtCore/QVariant>#include <QtGui/QAction>#include <QtGui/QApplication>#include <QtGui/QButtonGroup>#include <QtGui/QDialog>#include <QtGui/QFrame>#include <QtGui/QLabel>#include <QtGui/QLineEdit>#include <QtGui/QPushButton>QT_BEGIN_NAMESPACEclass Ui_DlgJFQ{public:    QFrame *frmjfq;    QLineEdit *txtAdded;    QLineEdit *txtAdd;    QLabel *lblAdd;    QPushButton *btnAdd;    QLabel *lblResult;    void setupUi(QDialog *DlgJFQ)    {    if (DlgJFQ->objectName().isEmpty())        DlgJFQ->setObjectName(QString::fromUtf8("DlgJFQ"));    DlgJFQ->resize(400, 100);    DlgJFQ->setMinimumSize(QSize(400, 100));    DlgJFQ->setMaximumSize(QSize(400, 100));    frmjfq = new QFrame(DlgJFQ);    frmjfq->setObjectName(QString::fromUtf8("frmjfq"));    frmjfq->setGeometry(QRect(9, 10, 381, 80));    frmjfq->setFrameShape(QFrame::Box);    frmjfq->setFrameShadow(QFrame::Sunken);    txtAdded = new QLineEdit(frmjfq);    txtAdded->setObjectName(QString::fromUtf8("txtAdded"));    txtAdded->setGeometry(QRect(10, 24, 100, 30));    txtAdd = new QLineEdit(frmjfq);    txtAdd->setObjectName(QString::fromUtf8("txtAdd"));    txtAdd->setGeometry(QRect(134, 24, 100, 30));    lblAdd = new QLabel(frmjfq);    lblAdd->setObjectName(QString::fromUtf8("lblAdd"));    lblAdd->setGeometry(QRect(113, 27, 20, 22));    QFont font;    font.setPointSize(18);    font.setBold(true);    font.setWeight(75);    lblAdd->setFont(font);    lblAdd->setAlignment(Qt::AlignCenter);    btnAdd = new QPushButton(frmjfq);    btnAdd->setObjectName(QString::fromUtf8("btnAdd"));    btnAdd->setGeometry(QRect(236, 22, 31, 32));    btnAdd->setFont(font);    btnAdd->setFlat(false);    lblResult = new QLabel(frmjfq);    lblResult->setObjectName(QString::fromUtf8("lblResult"));    lblResult->setGeometry(QRect(270, 23, 101, 31));    lblResult->setFrameShape(QFrame::Box);    lblResult->setFrameShadow(QFrame::Raised);    retranslateUi(DlgJFQ);    QMetaObject::connectSlotsByName(DlgJFQ);    } // setupUi    void retranslateUi(QDialog *DlgJFQ)    {    DlgJFQ->setWindowTitle(QApplication::translate("DlgJFQ", "\345\212\240\346\263\225\345\231\250", 0, QApplication::UnicodeUTF8));    lblAdd->setText(QApplication::translate("DlgJFQ", "+", 0, QApplication::UnicodeUTF8));    btnAdd->setText(QApplication::translate("DlgJFQ", "=", 0, QApplication::UnicodeUTF8));    lblResult->setText(QApplication::translate("DlgJFQ", "result", 0, QApplication::UnicodeUTF8));    Q_UNUSED(DlgJFQ);    } // retranslateUi};namespace Ui {    class DlgJFQ: public Ui_DlgJFQ {};} // namespace UiQT_END_NAMESPACE#endif // FRMJFG_H


dlgjfq.h

#ifndef DLG_JFQ_H#define DLG_JFQ_H#include <QDialog>#include "frmjfg.h"class DlgJFQ : public QDialog{Q_OBJECTprivate: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=appSOURCES=main.cpp\dlgjfq.cppHEADERS=frmjfg.h\dlgjfq.hCONFIG=release qtQT=core guiTARGET=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
常规属性
几何属性:
图标
光标
标题

基本事件(绘制/鼠标事件/键盘事件)

 main.cpp

#include <QApplication>#include <QWidget>#include <QIcon>int main(int args,char**argv){QApplication app(args,argv);QWidget w;//几何属性/*QSize size(400,400);w.resize(size);w.move(QPoint((1024-400)/2,(768-400)/2));*/w.setGeometry(QRect((1024-400)/2,(768-400)/2,400,400));//光标属性QCursor cur(Qt::PointingHandCursor);w.setCursor(cur);QIcon ico("ok.png");w.setWindowIcon(ico);w.setToolTip("<font size='45' color=red>Hello</font><img src='ok.png' width='100'  height='100'/>");w.setVisible(true);return app.exec();}




0 0