昨天出了一个小bug, 一直调都没调出来, 今天仔细看了下, 发现出错的原因了.

我在用osgEarth的时候, 用到一个类MapCatalogWidget, 觉得它不够用, 就把这个类给改了下, 添加了个slot:

public slots:
void addViewpoint(Viewpoint& vp);

这里由于MapCatalogWidget类自己已经添加了命名空间的引用, 所以想当然的在这里就没有使用 osgEarth::Viewpoint 这样的方式.

添加信号, 槽:

connect(manip, SIGNAL(viewpoint(osgEarth::Viewpoint&)),
vpCatalog, SLOT(addViewpoint(osgEarth::Viewpoint&)));

结果添加完后, 怎么也不响应, 而且输出窗口出还出现这么一句话:

Object::connect: No such slot osgEarth::QtGui::MapCatalogWidget::addViewpoint(osgEarth::Viewpoint&)

明明自己写了啊, 怎么就找不着呢....

经过分析, 觉得应该是出在moc处理slot上, 查看了下moc_MapCatalogWidget.cpp文件, 就发现了问题:

static const char qt_meta_stringdata_osgEarth__QtGui__MapCatalogWidget[] = {
"osgEarth::QtGui::MapCatalogWidget\0\0"
"onMapChanged()\0onSelectionChanged()\0"
"item,col\0onTreeItemDoubleClicked(QTreeWidgetItem*,int)\0"
"onTreeItemChanged(QTreeWidgetItem*,int)\0"
"onTreeSelectionChanged()\0pos\0"
"onTreeNodeRClick(QPoint)\0editModel()\0"
"vp\0addViewpoint(Viewpoint&)\0delViewpoint()\0"
};

void osgEarth::QtGui::MapCatalogWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
  if (_c == QMetaObject::InvokeMetaMethod) {
    Q_ASSERT(staticMetaObject.cast(_o));
    MapCatalogWidget *_t = static_cast<MapCatalogWidget *>(_o);
    switch (_id) {
      case 0: _t->onMapChanged(); break;
      case 1: _t->onSelectionChanged(); break;
      case 2: _t->onTreeItemDoubleClicked((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
      case 3: _t->onTreeItemChanged((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
      case 4: _t->onTreeSelectionChanged(); break;
      case 5: _t->onTreeNodeRClick((*reinterpret_cast< const QPoint(*)>(_a[1]))); break;
      case 6: _t->editModel(); break;
      case 7: _t->addViewpoint((*reinterpret_cast< Viewpoint(*)>(_a[1]))); break;
      case 8: _t->delViewpoint(); break;
      default: ;
    }
  }
}

可以看出这里moc解析slot后, 会得到这样一组字符串数组, 然后用数组中的"特殊"字符串的索引来做case, 以映射到对应的函数中.

这里之所以说是特殊字符串, 你可以仔细看看那个字符串数组, 它是分为两个部分, 用"\0\0"分隔开, 第一部分是类名, 第二部分是函数名, 这里函数如果带参数的话, 参数是放在函数名前的, 函数名和参数名都用"\0"来分隔的 (这里真心佩服qt的团队, 这种办法也想得出来.....).

看完这里的代码, 其实connect函数干的事情应该也能分析出个大概:

1. 把SIGNAL和SLOT宏的参数转换成字符串

2. 在实际调用的时候, Qt会将发出的信息, 转换得到匹配的槽

3. 再转到槽类中, 用字符串匹配到对应的函数来执行.

connect(manip, SIGNAL(viewpoint(Viewpoint&)),
vpCatalog, SLOT(addViewpoint(Viewpoint&)));

这里要注意一下, 两个域约束符号要去都要去, 否则运行时, qt会在输出窗口中提示你:

QObject::connect: Incompatible sender/receiver arguments
UIManipulator::viewpoint(osgEarth::Viewpoint&) --> osgEarth::QtGui::MapCatalogWidget::addViewpoint(Viewpoint&)

问题了解了, 解决就比较简单了!

我这里只要把MapcatalogWidget中的槽函数声明加上域约束符就OK了.

public slots:
void addViewpoint(osgEarth::Viewpoint& vp);

希望能帮上有同样问题的朋友.

Qt里的slot的更多相关文章

  1. Qt里怎么处理二进制数据

    Qt里有个专门的类QDataStream就是专门读写二进制数据的, 它与QByteArray搭配在网络编程中有奇效. 来个栗子: // write data QByteArray data; QDat ...

  2. Qt里获取目录的一个另类方法

    如果有一个文件的全路径文件名, 想获取它的路径的话, qt里我没找到比较好的办法, 都是cleanPath后, 再用QString的find, left这种函数来处理. 今天又在搞这种问题的时候, 看 ...

  3. Qt Signal and Slot

    Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...

  4. QT里使用sqlite的问题,好多坑

    1. 我使用sqlite,开发机上好好的,测试机上却不行.后来发现是缺少驱动(Driver not loaded Driver not loaded),代码检查了又检查,发现应该是缺少dll文件(系统 ...

  5. qt里标识操作系统的宏

    qt文件里的 windows的宏是Q_WS_WIN32/*   The window system, must be one of: (Q_WS_x) MACX     - Mac OS X      ...

  6. QT中使用 slot 传递 opencv 中得Mat对象以及 使用多线程集成开源代码。

    关于 slot传递 Mat 对象 以前一直是使用 Qtimer 定时器,设定超时后读取 dialog 对象的 Mat成员实现在 UI 里显示图像,发现这样对以后集成其他面向过程的代码增加了复杂度. 所 ...

  7. 关于在Qt里让程序休眠一段时间的方法总结

    出处:http://hanzhaoxin.cnblogs.com/ Qt 为何没有提供 Sleep 论坛上不时见到有人问: Qt 为什么没有提供跨平台的 sleep 函数? 使用平台相关的 Sleep ...

  8. Qt链接网站SLOT

    void BottomToolWidget::openLink() { QString link = "http://www.baidu.com";//在.h中添加slot声明,在 ...

  9. QT里嵌入Python

    刚看到一个软件,叫做,明明是QT做的,却带了很多pyd文件(Python编译后的文件),上网一查,果然有这套相关的东西: https://doc.qt.io/archives/qq/qq23-pyth ...

随机推荐

  1. VBA笔记(一)

    开启VBA编程环境--VBE 方法一:按<Alt+F11>组合建 方法二:查看代码 宏设置 当然启用宏的设置方式不同,宏的启动方式也不一样. 首先打开"office 按钮&quo ...

  2. tyvj1097 mm不哭

    背景 Bless all rp++.. 描述 在一个数轴上,有n个MM(绝非恐龙!)在哭泣(5555~一直哭). tcboy也在这个数轴上,并恰好看到了这一幕,由于每个MM哭都会让tcboy损失一定的 ...

  3. Computer Vision: OpenCV, Feature Tracking, and Beyond--From <<Make Things See>> by Greg

    In the 1960s, the legendary Stanford artificial intelligence pioneer, John McCarthy, famously gave a ...

  4. 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

    我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...

  5. 如何对Azure磁盘性能进行测试

    Azure的云存储一直是Azure比较自豪的东西,想到AWS的LSA后面有若干个9,搞得大家都以为它的存储最优秀,其实不然,Azure存储到现在没有丢过客户1bit的数据,但是Azure不会去说我们的 ...

  6. java基础知识(一)数据类型(上)

    java的数据类型 由上图,java的数据类型分为基本数据类型.引用数据类型两大类. 1.基本数据类型 与c不同,java的各种数据类型占有固定长度的内存,与具体的软硬件平台无关:另外,每种数据类型都 ...

  7. mount img

    直接挂载img文件有时会有  mount:您必须指定文件系统类型   的错误,但加 -t ext2 等类型还是没用. 这是因为img文件包含了mbr引导导致的问题.解决方法如下: $sudo fdis ...

  8. JavaScript刷新页面n种方法

    window.location.href 属性 window.location.href=window.location.href;//刷新当前页面 asp.net 或 asp 利用此功能刷新页面 R ...

  9. MFCC特征提取(C语言版本)

    音频分析中,MFCC参数是经典参数之一.之前对于它的计算流程和原理,大体上是比较清楚的,所以仿真的时候,都是直接调用matlab的voicebox工具或者开发的时候直接调用第三方库.最近想整理一个纯C ...

  10. android studio--百度定位集成001

    安卓现在的大趋势已经是普遍使用androidstudio(安装包[https://yunpan.cn/ckc54idj3JVJb  访问密码 664f])了.这个是集成的一个好的环境. 今天来搞个百度 ...