当前位置: 首页 > news >正文

Qt那点事儿(二)

第二回 拒签,不只天朝有

上回说到,柯南君展示了Qt无耻的一面后,众道友心灰意冷。修仙的修仙,搞基的搞基。原本热闹的Qt道场,一下子冷清了下来。只剩哥一个人坐在联想大厦的塑像前作冥想状,“世界如果失去了Qt会怎样“?会变成知书识仪,天下大同的理想世界吗?中国五千年的24部血泪史昭示了”This is just a dream“。一个无耻倒下了,一个更无耻的又站起来。这时大屏幕上的图片映入贫道的眼帘,

霎那间贫道的内心被震撼了,终于领悟了修仙的真谛,那就是“誓将揭露Qt无耻的事业进行到底”。此时的哥又斗志昂扬,走在了修仙的大道上。

各位道友请看此例,

void NotifyOtherThread(DWORD dwOtherThreadID)
{
    CString str = "i am here";
    ::PostThreadMessage(dwOtherThreadID,
        WS_NOTIFY,
        &str,
        NULL);

}

   我们知道在Windows的世界里,用Post跨线程发送消息是异步的,如果按照上面的实例,把local 类(结构)变量作为参数发送,那么接受方得到的参数内容会是混乱的,从而引起程序的崩溃。因为他一出函数体就被释放掉了。所以,我们从小就被告知,local类变量不能作为Post的参数。

 那么在Qt中还是这样吗?

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
       signalMyTestA("I am here.");
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA(QString str);
};

class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB(QString str)
    {
        qDebug()<<"string is "<<str;
    }
signals:
    void signalMyTestB();
};

extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    MyTestC():QThread(NULL)
    {
    }

    void run()
    {
        MyTestA a;
        QObject::connect(&a,SIGNAL(signalMyTestA(QString)),g_pMyTestB,SLOT(slotMyTestB(QString)));
        a.emitSignal();
        exec();
    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();


};

///

MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    MyTestB b;
    g_pMyTestB = &b;

    MyTestC c;
    c.start();



    return app.exec();
}

只见输出窗口打出了:string is  "I am here." 居然没有发生对象混乱,程序安然无恙,Local QString参数完美地被发送到了另外的线程。众道友的失落的心又重新热了起来,内心对Qt又充满了无限的期望。但俗话说得好,一朝被蛇咬,十年怕井绳。一些细心的道友,又把QString换成了QByteArray,QDate,QPixmap等常用的Qt类,无一错乱。十分,十分,只见铺天盖地的写有十的积分牌举了起来。此时语言已经是多余的了。终于不用再为Local变量烦恼了,跨线程不能使用Local变量这一无耻的行规终于被扫入了历史的垃圾箱。从此Coder道友们站起来了........。在一片赞扬声中,贫道则陷入了深深的思索中,事有反常即为妖。

突然思绪一闪,柯南君的音容相貌又浮现在了眼前。此时贫道把代码稍微改写了下

struct sOwn
{
   QString m_str;
};

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        sOwn s;
        s.m_str = "i am here";
        signalMyTestA(s);
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA(sOwn sItem);
};

class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB(sOwn sItem)
    {
        qDebug()<<"string is "<<sItem.m_str;
    }
signals:
    void signalMyTestB();
};

extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    MyTestC():QThread(NULL)
    {
    }

    void run()
    {
        MyTestA a;
        QObject::connect(&a,SIGNAL(signalMyTestA(sOwn)),g_pMyTestB,SLOT(slotMyTestB(sOwn)));
        a.emitSignal();
        exec();
    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();


};

/

MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    MyTestB b;
    g_pMyTestB = &b;

    MyTestC c;
    c.start();



    return app.exec();
}

一道闪电从空中划过,当代码执行到"QObject::connect(&a,SIGNAL(signalMyTestA(sOwn)),g_pMyTestB,SLOT(slotMyTestB(sOwn)));"这一句时,”QObject::connect: Cannot queue arguments of type 'sOwn' “刺眼地跳了出来。这句话通俗地说就是,你被发好人卡了,你被拒签了..., 总之就是因为你的对象不是Q家人,你就进不了Q家门,自然就connect不了slot。

这一刻Qt你又赢了,你又一次玩弄了众道友的感情,你继承了中国足球的光荣的传统。各届国家队在这一刻灵魂附体!在这一刻你不是一个人在战斗!你就像中国足球那样,在人绝望的时候给人希望,在希望的时候给人以绝望。

此时众道友仰天长叹,大声质问道,Qt你来自希望国,秉承着“All object is created equal”的信念(Qt内牛满面,哥本挪威人,奈何成花旗),却行歧视之勾当,意欲何为?更有欲到花旗传道的道友,挥舞着印有No Pass的护照,叹道,“人被拒签,难道自己写的程序也要被拒签,朗朗乾坤,公理何在,天理何存”。说完就要自碎金丹,化作散仙,不再为这个充满着无耻之徒的尘世所困扰。就在这时,一道红光飞过,仔细一看是一条鲜红的红领巾,上面写着几个屎黄色的希望文:

"qRegisterMetaType"

落款人:红领巾。

贫道急忙把此函数放到代码中,

struct sOwn
{
   QString m_str;
};

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        sOwn s;
        s.m_str = "i am here";
        signalMyTestA(s);
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA(sOwn sItem);
};

class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB(sOwn sItem)
    {
        qDebug()<<"string is "<<sItem.m_str;
    }
signals:
    void signalMyTestB();
};

extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    MyTestC():QThread(NULL)
    {
    }

    void run()
    {
        MyTestA a;
        qRegisterMetaType<sOwn>("sOwn");
        QObject::connect(&a,SIGNAL(signalMyTestA(sOwn)),g_pMyTestB,SLOT(slotMyTestB(sOwn)));
        a.emitSignal();
        exec();
    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();


};
/

MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    MyTestB b;
    g_pMyTestB = &b;

    MyTestC c;
    c.start();



    return app.exec();
}

string is  "I am here." 重回大地,众人又开始捻胡微笑,皆叹Qt的人性化。不用收入证明,不用公司邀请信,不用签证面试,只要你用了qRegisterMetaType,你就是Q家人了。

所以,当signal异步调用slot时,如果你的对象不是Qt所支持的,就需要调用qRegisterMetaType,而后就可以将Local class变量放到signal中,安全地传递给slot。

一切就是这么简单。Ye!!!,众道友做了个00后的标准动作,以表达自己的欢乐之情。

但是快乐的时光总是短暂的,又一幕悲剧拉开了序幕。

话说C++三朝元老,int。最近痴迷欧美音乐,给自己取了个鼎鼎响亮的艺名"雷帝嘎嘎"(LADYGAGA)。结果,

typedef int LADYGAGA;

struct sOwn
{
   QString m_str;
};

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        int i = 9;
        signalMyTestA(i);
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA(LADYGAGA lg);
};

class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB(LADYGAGA lg)
    {
        qDebug()<<"string is "<<lg;
    }
signals:
    void signalMyTestB();
};

extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    MyTestC():QThread(NULL)
    {
    }

    void run()
    {
        MyTestA a;
        QObject::connect(&a,SIGNAL(signalMyTestA(LADYGAGA)),g_pMyTestB,SLOT(slotMyTestB(LADYGAGA)));
        a.emitSignal();
        exec();
    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();


};
//
MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);


    MyTestB b;
    g_pMyTestB = &b;

    MyTestC c;
    c.start();



    return app.exec();
}

本年度最具爆炸性新闻诞生了“QObject::connect: Cannot queue arguments of type 'LADYGAGA',(Make sure 'LADYGAGA' is registered using qRegisterMetaType().)”世界震惊了,大家宁可相信“发改委宣布降低油价”,也不愿相信,编程界基本数据类型的三朝元老,久经考验的C++主义战士,int同志居然因为使用众人皆知的艺名connect slot,被拒签了。三大社(美联社,法新社,路透社)联合发文<<悲剧,三朝元老使用艺名,被拒签>>。2月30号X民日报头版发表评论员文章《老同志,倚老卖老要不得》。

从上诉评论中我们不难看出"当signal和slots是异步时,哪怕数据类型用qRegisterMetaTyoe注册过,甚至是基本数据类型,connect用的参数类型不是注册名,而是typedef或者define的别名,connect也会失败,如果要使用别名,也需要对别名进行重新注册。Qt只认名,不认人"。对于上面的例子,如果要使connect能正常使用,需调用qRegisterMetaType<LADYGAGA>("LADYGAGA");,虽然LADYGAGA其实就是int。

Qt总是在意想不到的时间,意想不到的地点,展示其无耻的一面。

太史公曾曰,世上无耻者,皆不过Qt也。

古人不曾欺我。

而众道友此时却没有因为Qt的再次无耻,而愤愤不平,反而露出一丝猥琐的笑容,心里不禁乐道,老东西,你也有今天。

而贫道又陷入了沉思,Qt你的底线到底在哪里?

欲知后事如何,请看下回分解。




转载于:https://www.cnblogs.com/andreitang/archive/2011/08/08/2128505.html

相关文章:

  • 30岁前男人需要完成的事
  • An Implementation of SOPC-based Framework for Image Processing
  • .net/c# memcached 获取所有缓存键(keys)
  • linux centos 防火墙设置
  • 为什么要设置Java环境变量(详解)
  • 魔兽1.20E作弊内存地址全公开
  • windows下搭建eclipse+pyghon+pygame的开发环境
  • web.xml配置详解
  • MySQL分区
  • 学习.NET Framework相关经验总结概览
  • (转)nsfocus-绿盟科技笔试题目
  • JQuery上传插件Uploadify出现HTTP Error错误的解决办法
  • 如何清除局域网访问计算机的用户密码
  • htmlParser for delphi
  • ASP.NET显示农历时间
  • 03Go 类型总结
  • Android 架构优化~MVP 架构改造
  • CentOS从零开始部署Nodejs项目
  • JavaScript类型识别
  • PHP那些事儿
  • vue学习系列(二)vue-cli
  • 京东美团研发面经
  • 老板让我十分钟上手nx-admin
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 如何优雅地使用 Sublime Text
  • 使用docker-compose进行多节点部署
  • 我看到的前端
  • 协程
  • 异步
  • 用element的upload组件实现多图片上传和压缩
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​TypeScript都不会用,也敢说会前端?
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • $.ajax()参数及用法
  • (1)(1.9) MSP (version 4.2)
  • (Matlab)使用竞争神经网络实现数据聚类
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (汇总)os模块以及shutil模块对文件的操作
  • (算法二)滑动窗口
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)EXC_BREAKPOINT僵尸错误
  • .java 9 找不到符号_java找不到符号
  • .NET Core 版本不支持的问题
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .NET大文件上传知识整理
  • .NET学习全景图
  • :=
  • ?.的用法
  • @Autowired 与@Resource的区别
  • @GlobalLock注解作用与原理解析
  • @RequestBody与@ResponseBody的使用
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • []我的函数库
  • [20150904]exp slow.txt
  • [Big Data - Kafka] kafka学习笔记:知识点整理