您的位置:首页 > 其它

信号与槽

2015-06-28 16:21 555 查看
回顾:

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_OBJECT
private:
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_OBJECT
private:
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=app
SOURCES=main.cpp	\
biz.cpp		\
log.cpp
HEADERS=log.h		\
biz.h
CONFIG=release qt
QT=core
TARGET=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_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();
}


main.pro

TEMPLATE=app
SOURCES=main.cpp	\
mydialog.cpp

HEADERS=mydialog.h

CONFIG=release qt
QT=core gui
TARGET=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_NAMESPACE

class 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 Ui

QT_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_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

常规属性

几何属性:

图标

光标

标题

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

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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: