声明:此文章仅是本人在学习狄泰QT实验分析课程所做的笔记,文章中包含狄泰软件资料内容,一切版权归狄泰软件所有!
实验环境:ubuntu10 + Qt Creator2.4.1 + Qt SDK 4.7.4
1. Qt消息模型
Qt封装了具体操作系统的消息机制,Qt遵循经典的GUI消息驱动事件模型
问题:
1) Qt中如何表示用户消息?
2) Qt中如何映射用户消息到消息处理函数?
3) Qt中消息映射需要遵循什么规则?
2. 信号(Signal)与槽(Slot)
(1) Qt中定义了与系统消息相关的概念:
信号(Signal):由操作系统产生的消息
槽(Slot):程序中的消息处理函数
连接(Connect):将系统消息绑定到消息处理函数
(2) Qt中消息处理机制
note: 信号到槽的连接必须发生在两个Qt类对象之间!!!
(3) Qt的核心—QObject::connect
函数
note:
1)在Qt中,消息用字符串进行描述
2)connect函数在消息名和处理函数之间**建立映射
(4) Qt中的新关键字
SIGNAL
:用于指定消息名
SLOT
:用于指定消息处理函数名
Q_OBJECT
:所有自定义槽的类必须在类声明的开始处加上Q_OBJECT
slots
:用于在类中声明消息处理函数
编程说明:信号与槽的初探
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton b;
b.setText("Click me to quit!");
b.show();
// connect函数
QObject::connect(
&b,
SIGNAL(clicked()),
&a,
SLOT(quit()),
Qt::AutoConnection);
return a.exec();
}
输出结果:
点击后退出
3. 自定义槽
- 只有
QObject
的子类才能自定义槽 - 定义槽的类必须在声明的最开始处使用
Q_OBJECT
- 类中声明槽时需要使用
slots
关键字 - 槽与所处理的信号在函数签名上必须一致
-
SIGNAL
和SLOT
所指定的名称中:可以包含参数类型, 不能包含具体的函数名
编程说明:为计算器实例添加消息处理函数
QCalcutorUI.h
#ifndef _QCALCULATORUI_H_
#define _QCALCULATORUI_H_
#include
#include
#include
class QCalculatorUI : public QWidget
{
Q_OBJECT
private:
QLineEdit* m_edit;
QPushButton* m_button[20];
QCalculatorUI();
bool construct();
private slots: // 添加消息处理函数
void onButtonClicked();
public:
static QCalculatorUI* NewInstance();
void show();
~QCalculatorUI();
};
#endif
QCalcutorUI.cpp
#include "QCalculatorUI.h"
#include
QCalculatorUI::QCalculatorUI() : QWidget(NULL, Qt::WindowCloseButtonHint)
{
}
bool QCalculatorUI::construct()
{
bool ret = true;
const char* butText[20] =
{ "7", "8", "9", "+", "(",
"4", "5", "6", "-", ")",
"1", "2", "3", "*", "<-",
"0", ".", "=", "/", "C",
};
m_edit = new QLineEdit(this);
if(m_edit != NULL)
{
m_edit->move(10, 10);
m_edit->resize(240, 30);
m_edit->setReadOnly(true);
}
else
{
ret = false;
}
for(int i=0; (i<4) && ret; ++i)
{
for(int j=0; (j<5) && ret; ++j)
{
m_button[i*5+j] = new QPushButton(this);
if(m_button[i*5+j] != NULL)
{
m_button[i*5+j]->move(10+50*j, 50+50*i);
m_button[i*5+j]->resize(40, 40);
m_button[i*5+j]->setText(butText[i*5+j]);
// 连接消息与消息处理函数
connect(m_button[i*5+j],
SIGNAL(clicked()),
this,
SLOT(onButtonClicked()));
}
else
{
ret = false;
}
}
}
return ret;
}
QCalculatorUI* QCalculatorUI::NewInstance()
{
QCalculatorUI* ret = new QCalculatorUI();
if( (ret == NULL) || !(ret->construct()) )
{
delete ret;
ret = NULL;
}
return ret;
}
void QCalculatorUI::show()
{
QWidget::show();
setFixedSize(width(), height());
}
void QCalculatorUI::onButtonClicked() // 实现消息处理函数
{
QPushButton* btn = (QPushButton*)sender(); // 获取发送方对象的指针
qDebug() << "onButtonClicked";
qDebug() << btn->text(); // 获取发送方字符串
}
QCalculatorUI::~QCalculatorUI()
{
}
main.cpp
#include
#include
#include "QCalculatorUI.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QCalculatorUI* cal= QCalculatorUI::NewInstance();
int ret = -1;
if(cal != NULL)
{
cal->show();
ret = a.exec();
delete cal;
}
else
{
qDebug() << " Instance failure";
}
return ret;
}
4. 小贴士
- 解决经典问题:
Object::connect:NO such slot...
- 检查类是否继承于
QObject
- 检查类声明的开始处是否添加
Q_OBJECT
- 检查是否使用
slots
关键字进行槽声明 - 检查槽名称是否拼写错误
- 重新执行
qmake
5. 小结
- 信号与槽是Qt中的核心机制
- 不同的Qt对象可以通过信号和槽进行通信
- 只有
QObject
的子类才能自定义信号和槽 - 使用信号和槽的类必须在声明的最开始处使用
Q_OBJECT
- 信号与处理函数在函数签名上必须一致