加载中…
个人资料
来一桶
来一桶
  • 博客等级:
  • 博客积分:0
  • 博客访问:7,582
  • 关注人气:1
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
正文 字体大小:

我的专属QQ (三) 附源码 (转)

(2012-03-15 22:27:24)
标签:

杂谈

分类: QT
   要源码的朋友太多了,满眼的邮箱地址,我很头疼。鉴于现在CSDN首页的Qt应用大赛正在火热进行中,我干脆把源码奉献出来,给大家参考一下好了。不过,这不是我一个人的劳动成果,我一直认为技术领域的最高境界是分享,所以希望得到你的尊重。

       有什么好的意见和建议欢迎你提,但是请注意语气。我写博客的目的有两个,一是记录,二是分享。我记录我的学习历程,分享给大家。我不是神,我想神也不能精通各个技术领域,不是最好的方案你就冷嘲热讽,于情于理都不太合适吧。我这又不是出书,你掏腰包买了看了觉得不好,骂几句才痛快。我自己写我的自己博客,你发现瑕疵,是好事,欢迎你提出来,哪来那么大火气我就不懂了。你能写出更好的,我向你学习。如若不然,在写出作品之前,请别带着一副大爷的嘴脸耍青皮。

   

       请原谅我说了那么多前言范er的废话,我最后再说说关于QThread 的用法,tcpSocket起一个线程去读取用户注册信息这么一档子事。

      

   

 

 

 

 

        线程,就是这么个模子:

       

  1. TcpConThread::TcpConThread(int socketDescriptor, QObject *parent)  
  2.         QThread(parent), socketDescriptor(socketDescriptor)  
  3.  
  4.     ...  
  5.  
  6.   
  7. void TcpConThread::run()  
  8.  
  9.    ...  
  10.  

 

备个注吧:QThread类提供了与系统无关的线程。

QThread代表在程序中一个单独的线程控制,在多任务操作系统中,它和同一进程中的其它线程共享数据,但运行起来就像一个单独的程序一样。它不是在main()中开始,QThread是在run()中开始运行的。你继承run()并且在其中包含你的代码。例如:

  1. class MyThread public QThread  
  2.   
  3.     public 
  4.   
  5.         virtual void run();  
  6.   
  7.     };  
  8.   
  9.     void MyThread::run()  
  10.      
  11.         forint count 0; count 20; count++  
  12.             sleep( );  
  13.             qDebug( "Ping!" );  
  14.          
  15.      
  16.   
  17.     int main()  
  18.      
  19.         MyThread a;  
  20.         MyThread b;  
  21.         a.start();  
  22.         b.start();  
  23.         a.wait();  
  24.         b.wait();  
  25.      

    

void QThread::run () [纯虚 保护]
这个方法是纯虚的,并且为了能够做有用的工作必须在继承类中被重新实现。这个方法的返回将会结束线程的执行。

void QThread::start ()
通过调用run()(必须在QThread子类中重新实现来包含你的代码)开始这个线程的执行。如果你试图开始一个已经运行的线程,这个调用将一直等待,直到这个线程完成,然后再重新开始这个线程。

void QThread::exit () [静态]

结束调用线程的执行并且唤醒任何等待它终止的线程。

 

bool QThread::wait ( unsigned long time = ULONG_MAX )

这将提供和POSIX pthread_join相似的功能。一个线程调用了它将会一直阻塞,知道下述条件之一满足时继续:

1.这个QThread对象所关联的线程已经结束执行(比如,当它从run()中返回)。如果线程完成,这个函数将返回真。如果线程还没有开始呢,这个函数也返回真。

2.time毫秒过去了。如果time是ULONG_MAX(默认值),然后等待将永远不会超时(线程必须从run()中返回)。如果等待时间到了,这个函数将返回假。

 

 

 

想在线程里干什么,就在run()里写什么,在这里的实现很简单,内容都在on_Ready_Read()的实现里

 

  1. void TcpConThread::run()  
  2.  
  3.   
  4.     tcpSocket new QTcpSocket;  
  5.   
  6.     connect(tcpSocket, SIGNAL(readyRead()), thisSLOT(on_Ready_Read()));  
  7.   
  8.     if (!tcpSocket->setSocketDescriptor(socketDescriptor))  
  9.      
  10.         emit error(tcpSocket->error());  
  11.         return 
  12.      
  13.         exec();  
  14.   
  15.  

这个exec() 就是把整个进程空间换成要执行的那个程序的进程空间,说白了就把自己换成别人。

 

  1. void TcpConThread::on_Ready_Read()  
  2.  
  3.       
  4.   
  5.     db new SqliteDB;  
  6.   
  7.     QString ip tcpSocket->peerAddress().toString();  
  8.     qint16 port tcpSocket->peerPort();  
  9.   
  10.     QByteArray block tcpSocket->readAll();  
  11.     QDataStream in(&block, QIODevice::ReadOnly);     //QDataStream in(tcpSocket);   
  12.     quint16 dataGramSize;  
  13.     QString msgType;  
  14.     in >> dataGramSize >> msgType;  
  15.   
  16.     if "MSG_CLIENT_USER_REGISTER" == msgType  
  17.      
  18.         QString id;  
  19.         QString password;  
  20.         QString name;  
  21.         in >> id >> password >> name;  
  22.   
  23.         if == db->insertNewUser( id, password, name, ip, QString::number(port))  
  24.          
  25.             QMessageBox::warning(NULL, tr("提示"), tr("该号码已被注册."));  
  26.             QString msgType "MSG_ID_ALREADY_EXIST" 
  27.             QByteArray block;  
  28.             QDataStream out(&block, QIODevice::WriteOnly);  
  29.             out.setVersion(QDataStream::Qt_4_6);  
  30.             out << (quint16)0 << msgType;  
  31.             out.device()->seek(0);  
  32.             out << (quint16)(block.size() sizeof(quint16));  
  33.             tcpSocket->write(block);  
  34.          
  35.         else  
  36.          
  37.             QByteArray block;  
  38.   
  39.             QDataStream out(&block, QIODevice::WriteOnly);  
  40.             out.setVersion(QDataStream::Qt_4_6);  
  41.             QString msgType "MSG_REGISTER_SUCCESS" 
  42.             out << (quint16)0 << msgType;  
  43.             out.device()->seek(0);  
  44.             out << (quint16)(block.size() sizeof(quint16));  
  45.             tcpSocket->write(block);  
  46.          
  47.      
  48.     else if "MSG_USER_LOGIN" == msgType  
  49.      
  50.         QString id;  
  51.         QString password;  
  52.         in >> id >> password;  
  53.         db->getUserInfo(id);  
  54.   
  55.         if (db->strListUser.isEmpty())        //MSG_ID_NOTEXIST   
  56.          
  57.              QMessageBox::critical(NULL, tr("提示"), tr("没有名字");  
  58.             QByteArray block;  
  59.             QDataStream out(&block, QIODevice::WriteOnly);  
  60.             out.setVersion(QDataStream::Qt_4_6);  
  61.             QString msgType "MSG_ID_NOTEXIST" 
  62.             out << (quint16)0 << msgType;  
  63.             out.device()->seek(0);  
  64.             out << (quint16)(block.size() sizeof(quint16));  
  65.             tcpSocket->write(block);  
  66.   
  67.          
  68.         else if(db->strListUser.at(1) != password)        //MSG_PWD_ERROR   
  69.          
  70.   
  71.             QByteArray block;  
  72.             QDataStream out(&block, QIODevice::WriteOnly);  
  73.             out.setVersion(QDataStream::Qt_4_6);  
  74.             QString msgType "MSG_PWD_ERROR" 
  75.             out << (quint16)0 << msgType;  
  76.             out.device()->seek(0);  
  77.             out << (quint16)(block.size() sizeof(quint16));  
  78.             tcpSocket->write(block);  
  79.          
  80.         else if (db->strListUser.at(1) == password  
  81.          
  82.             if ((db->strListUser.at(3)) == "1"         //MSG_LOGIN_ALREADY   
  83.              
  84.   
  85.                 QByteArray block;  
  86.                 QDataStream out(&block, QIODevice::WriteOnly);  
  87.                 out.setVersion(QDataStream::Qt_4_6);  
  88.                 QString msgType "MSG_LOGIN_ALREADY" 
  89.                 out << (quint16)0 << msgType;  
  90.                 out.device()->seek(0);  
  91.                 out << (quint16)(block.size() sizeof(quint16));  
  92.                 tcpSocket->write(block);  
  93.   
  94.   
  95.              
  96.             else            //MSG_LOGIN_SUCCESS   
  97.              
  98.                 QByteArray block;  
  99.                 QDataStream out(&block, QIODevice::WriteOnly);  
  100.                 out.setVersion(QDataStream::Qt_4_6);  
  101.                 QString msgType "MSG_LOGIN_SUCCESS" 
  102.                 out << (quint16)0 << msgType;  
  103.                 out.device()->seek(0);  
  104.                 out << (quint16)(block.size() sizeof(quint16));  
  105.                 tcpSocket->write(block);  
  106.                 //login success, update database   
  107.                 db->updateUserLogStat(id, "1");  
  108.                 db->updateUserIp(id,tcpSocket->peerAddress().toString());  
  109.              
  110.   
  111.          
  112.      

还有请注意, QCoreApplication::exec() 必须从主线程(执行 main() 方法的线程)调用, 不从 QThread 调用。 在GUI应用程序,主线程也被称为GUI线程,因为它是唯一允许执行GUI相关操作的线程。

 

   

 

困死了还有一大堆工作没有做,整个工程的源码debug版 , release版都打包好上传至CSDN资源,本地没有Qt库也可以运行体验一下,很囧的是,我只能上传20M以下的资源,只好缩减了一些UI的特效显示,唉……只是些UI资源图片的删减无大碍,免费0积分下载:自定义QQ

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有