Signal & Slot in Qt
Try your best to provide an mechanism to implement what you want.
1. All is generated by QT Framework before compiling.
QObject.connect(sender,SIGNAL(signal()), reciver,SLOT(slot()));
==>
QObject.connect(sender, “2signal( )”,reciver,”1slot()”);
class QExample : public QObject
{ Q_OBJECT public:
QTestA (QObject *parent ); ~QTestA ();
signals:
void SignalA1 ();
void SignalA2 (int i ); public slots:
void SlotA1 ();
void SlotA2 (char *szBuf ,int nSize );
private: public: int qt_metacall (QMetaObject ::Call _c , int _id , void **_a )
{
_id = QObject ::qt_metacall (_c , _id , _a );
if (_id < )
return _id ;
if (_c == QMetaObject ::InvokeMetaMethod )
{
switch (_id ) {
case : SignalA1 (); break ;
case : SignalA2 ((*reinterpret_cast < int (*)>(_a []))); break ;
case : SlotA1 (); break ;
case : SlotA2 ((*reinterpret_cast < char *(*)>(_a [])),(*reinterpret_cast < int (*)>(_a []))); break ;
default : ;
}
_id -= ;
}
return _id ;
} };
2. Add additional meta data and function in class
QMetaObject
{
const QMetaObject *superdata ;
const char *stringdata ; //save class name, signal name, parameter name,slot name, all ended by '/0'
const uint *data ; //int array, store information of QMetaObjectPrivate
}
struct QMetaObjectPrivate { int revision ;
int className ;
int classInfoCount , classInfoData ;
int methodCount , methodData ;
int propertyCount , propertyData ;
int enumeratorCount , enumeratorData ;
int constructorCount , constructorData ;
};
3. Define your own macro, translate user input string into the real code
All below is added in order to find the right ID for cooresponding method of signal and slot
Example:
static const uint qt_meta_data_Q QExampleData[] = {
, // revision
, // classname
, , // classinfo
, , // methods and its data
, , // properties
, , // enums/sets
, , // constructors
// 以上部分 是QMetaObjectPrivate 结构信息
// signals: signature, parameters, type, tag, flags
, , , , 0x05,
, , , , 0x05,
// slots: signature, parameters, type, tag, flags
, , , , 0x0A,
, , , , 0x0A,
// end
};
// slots: signature, parameters, type, tag, flags
1 static const char qt_meta_stringdata_Q QExampleMetaData [] = {
"QTestA/0/0SignalA1()/0i/0SignalA2(int)/0"
"SlotA1()/0szBuf,nSize/0SlotA2(char*,int)/0"
};
4.And connection object to list
QMetaObject::connect(sender, signal_index,receiver, method_index,type, types);
QObject *s =const_cast<QObject*>(sender);
QObject*r = const_cast<QObject *>(receiver); QOrderedMutexLockerlocker(&s->d_func()->threadData->mutex, &r->d_func()->threadData->mutex); QObjectPrivate::Connection c; c.receiver = r;
c.method = method_index;
c.connectionType = type;
c.argumentTypes= types; s->d_func()->addConnection(signal_index, &c);
r->d_func()->refSender(s, signal_index);
QObject::connect(const QObject *sender,
const char *signal,
const QObject *receiver,
const char *method,
Qt::ConnectionType type)
{
{
const void *cbdata[] = { sender, signal, receiver, method, &type };
if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
return true;
} if (sender == || receiver == || signal == || method == ) {
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
sender ? sender->metaObject()->className() : "(null)",
(signal && *signal) ? signal+ : "(null)",
receiver ? receiver->metaObject()->className() : "(null)",
(method && *method) ? method+ : "(null)");
return false;
} QByteArray tmp_signal_name; if (!check_signal_macro(sender, signal, "connect", "bind"))
return false; const QMetaObject *smeta = sender->metaObject();
const char *signal_arg = signal;
++signal; //skip code
int signal_index = smeta->indexOfSignal(signal);
if (signal_index < ) {
// check for normalized signatures
tmp_signal_name = QMetaObject::normalizedSignature(signal - );
signal = tmp_signal_name.constData() + ; signal_index = smeta->indexOfSignal(signal);
if (signal_index < ) {
err_method_notfound(sender, signal_arg, "connect");
err_info_about_objects("connect", sender, receiver);
return false;
}
} QByteArray tmp_method_name;
int membcode = extract_code(method); if (!check_method_code(membcode, receiver, method, "connect"))
return false;
const char *method_arg = method;
++method; // skip code const QMetaObject *rmeta = receiver->metaObject();
int method_index = -;
switch (membcode) {
case QSLOT_CODE:
method_index = rmeta->indexOfSlot(method);
break;
case QSIGNAL_CODE:
method_index = rmeta->indexOfSignal(method);
break;
}
if (method_index < ) {
// check for normalized methods
tmp_method_name = QMetaObject::normalizedSignature(method);
method = tmp_method_name.constData();
switch (membcode) {
case QSLOT_CODE:
method_index = rmeta->indexOfSlot(method);
break;
case QSIGNAL_CODE:
method_index = rmeta->indexOfSignal(method);
break;
}
} if (method_index < ) {
err_method_notfound(receiver, method_arg, "connect");
err_info_about_objects("connect", sender, receiver);
return false;
}
if (!QMetaObject::checkConnectArgs(signal, method)) {
qWarning("QObject::connect: Incompatible sender/receiver arguments"
"\n %s::%s --> %s::%s",
sender->metaObject()->className(), signal,
receiver->metaObject()->className(), method);
return false;
} int *types = ;
if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
&& !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))
return false; QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
const_cast<QObject*>(sender)->connectNotify(signal - );
return true;
}
Signal & Slot in Qt的更多相关文章
- QT窗体间传值总结之Signal&Slot
在写程序时,难免会碰到多窗体之间进行传值的问题.依照自己的理解,我把多窗体传值的可以使用的方法归纳如下: 1.使用QT中的Signal&Slot机制进行传值: 2.使用全局变量: 3.使用pu ...
- 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- QT 中 关键字讲解(emit,signal,slot)
Qt中的类库有接近一半是从基类QObject上继承下来,信号与反应槽(signals/slot)机制就是用来在QObject类或其子类间通讯的方法.作为一种通用的处理机制,信号与反应槽非常灵活,可以携 ...
- signal & slot
The Qt signals/slots and property system are based on the ability to introspect the objects at runti ...
- Qt_深入了解信号槽(signal&slot)
转自豆子空间 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯.这就将类之间的关系做了最大程度的解耦. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使 ...
- QML于C++交互之信号与槽(signal&slot )
connect c++ SIGNAL with QML SLOT 简介 QML 与 C++ 混合编程时,总结了一下qml和c++互相直接调用.及信号与槽连接 的几种情况,详细使用情况看示例代码 所有的 ...
- Object::connect: No such slot (QT槽丢失问题)
1.看看你的类声明中有没有Q_OBJECT,并继承public QMainWindow{ 例如: class CPlot: public QMainWindow{ Q_OBJECT 2.你声明的函数要 ...
- qt的signal和slot机制
signal和slot是QT中的一大特点 signal/slot是Qt对象以及其派生类对象之间的一种高效通信接口 用户可以将N多个信号和单个槽相连接, 或者将将N个槽和单个信号连接, 甚至是一个信号和 ...
- MFC、WTL、WPF、wxWidgets、Qt、GTK、Cocoa、VCL 各有什么特点?
WTL都算不上什么Framework,就是利用泛型特性对Win API做了层封装,设计思路也没摆脱MFC的影响,实际上用泛型做UI Framework也只能算是一次行为艺术,这个思路下继续发展就会变得 ...
随机推荐
- 线段树+单调栈+前缀和--2019icpc南昌网络赛I
线段树+单调栈+前缀和--2019icpc南昌网络赛I Alice has a magic array. She suggests that the value of a interval is eq ...
- 关于MatlabGUI清除WorkSpace的用法
近日在调试Matlba GUI程序时,因为不想退出程序后手动Clear All来清理,又需要在过程中对WorkSpace进行清理,否则会引用之前的结果导致错误,找了很多资料,国内的论坛什么的都说用Cl ...
- (java/javascript) list 交集 并集 差集 去重复并集
java list 交集 并集 差集 去重复并集 package com; import java.util.ArrayList; import java.util.Iterator; import ...
- php 如何匹配中文或英文姓名
这几天在做项目的用户注册时,想限制用户使用一些比较奇怪的字符作为名字,即使用中文或者英文名字. 查了一些资料,例如:网友挥得更高的百度空间 写下了以下函数. //验证名字和密码 if (!preg_m ...
- PHP 对目录下所有TXT进行遍历 并正则进行处理 preg_replace
<?php set_time_limit(); //遍历 指定目录下的所有 文件/ $pattern是要匹配的 文件规则 function file_list($dir,$pattern=&qu ...
- 关于JNI调用从eclipse转到Android Studio遇到的问题(总结)
将一个小应用从eclipse开发迁移到android studio,程序中有native代码实现,在eclipse是靠Android.mk这么个mk文件来组织编译的,但到android studio上 ...
- JavaScript设计模式-13.组合模式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 运维监控之zabbix(yum安装)
简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位 ...
- dll ocx cab IE 自动安装
我们打开淘宝等网站时,IE浏览器会提示安装空间,这个控件便是用于对用户名密码进行加密的ActiveX控件.如何在我们的站点上安装如此控件,让用户可以通过简单的点击便可方便使用我们的空间呢? 下面是如何 ...
- Scrum 冲刺博客第三篇
一.当天站立式会议照片一张 二.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中 昨天已完成的工作 基本的页面设计 各个页面之间的跳转 背景音乐模块设计 今天计划完成的工作 ...