我的专属QQ (三) 附源码

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

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

   

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

      

   

 

 

 

 

        线程,就是这么个模子:

       

TcpConThread::TcpConThread(int socketDescriptor, QObject *parent)
        : QThread(parent), socketDescriptor(socketDescriptor)
{
    ...
}

void TcpConThread::run()
{
   ...
}

 

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

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

class MyThread : public QThread {

    public:

        virtual void run();

    };

    void MyThread::run()
    {
        for( int count = 0; count < 20; count++ ) {
            sleep( 1 );
            qDebug( "Ping!" );
        }
    }

    int main()
    {
        MyThread a;
        MyThread b;
        a.start();
        b.start();
        a.wait();
        b.wait();
    }


    

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()的实现里

 

void TcpConThread::run()
{

    tcpSocket = new QTcpSocket;

    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_Ready_Read()));

    if (!tcpSocket->setSocketDescriptor(socketDescriptor))
    {
        emit error(tcpSocket->error());
        return;
    }
        exec();

}

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

 

void TcpConThread::on_Ready_Read()
{
    /*QString strLogin = tcpSocket->readAll();
    QStringList strListUser = strLogin.split("|");
    QString id = strListUser.at(0);
    QString password = strListUser.at(1);*/

    db = new SqliteDB;

    QString ip = tcpSocket->peerAddress().toString();
    qint16 port = tcpSocket->peerPort();

    QByteArray block = tcpSocket->readAll();
    QDataStream in(&block, QIODevice::ReadOnly);     //QDataStream in(tcpSocket);
    quint16 dataGramSize;
    QString msgType;
    in >> dataGramSize >> msgType;

    if ( "MSG_CLIENT_USER_REGISTER" == msgType )
    {
        QString id;
        QString password;
        QString name;
        in >> id >> password >> name;

        if ( 0 == db->insertNewUser( id, password, name, ip, QString::number(port)) )
        {
            QMessageBox::warning(NULL, tr("提示"), tr("该号码已被注册."));
            QString msgType = "MSG_ID_ALREADY_EXIST";
            QByteArray block;
            QDataStream out(&block, QIODevice::WriteOnly);
            out.setVersion(QDataStream::Qt_4_6);
            out << (quint16)0 << msgType;
            out.device()->seek(0);
            out << (quint16)(block.size() - sizeof(quint16));
            tcpSocket->write(block);
        }
        else
        {
            QByteArray block;

            QDataStream out(&block, QIODevice::WriteOnly);
            out.setVersion(QDataStream::Qt_4_6);
            QString msgType = "MSG_REGISTER_SUCCESS";
            out << (quint16)0 << msgType;
            out.device()->seek(0);
            out << (quint16)(block.size() - sizeof(quint16));
            tcpSocket->write(block);
        }
    }
    else if ( "MSG_USER_LOGIN" == msgType )
    {
        QString id;
        QString password;
        in >> id >> password;
        db->getUserInfo(id);

        if (db->strListUser.isEmpty())        //MSG_ID_NOTEXIST
        {
             QMessageBox::critical(NULL, tr("提示"), tr("没有名字") );
            QByteArray block;
            QDataStream out(&block, QIODevice::WriteOnly);
            out.setVersion(QDataStream::Qt_4_6);
            QString msgType = "MSG_ID_NOTEXIST";
            out << (quint16)0 << msgType;
            out.device()->seek(0);
            out << (quint16)(block.size() - sizeof(quint16));
            tcpSocket->write(block);

        }
        else if(db->strListUser.at(1) != password)        //MSG_PWD_ERROR
        {

            QByteArray block;
            QDataStream out(&block, QIODevice::WriteOnly);
            out.setVersion(QDataStream::Qt_4_6);
            QString msgType = "MSG_PWD_ERROR";
            out << (quint16)0 << msgType;
            out.device()->seek(0);
            out << (quint16)(block.size() - sizeof(quint16));
            tcpSocket->write(block);
        }
        else if (db->strListUser.at(1) == password )
        {
            if ((db->strListUser.at(3)) == "1")          //MSG_LOGIN_ALREADY
            {

                QByteArray block;
                QDataStream out(&block, QIODevice::WriteOnly);
                out.setVersion(QDataStream::Qt_4_6);
                QString msgType = "MSG_LOGIN_ALREADY";
                out << (quint16)0 << msgType;
                out.device()->seek(0);
                out << (quint16)(block.size() - sizeof(quint16));
                tcpSocket->write(block);


            }
            else            //MSG_LOGIN_SUCCESS
            {
                QByteArray block;
                QDataStream out(&block, QIODevice::WriteOnly);
                out.setVersion(QDataStream::Qt_4_6);
                QString msgType = "MSG_LOGIN_SUCCESS";
                out << (quint16)0 << msgType;
                out.device()->seek(0);
                out << (quint16)(block.size() - sizeof(quint16));
                tcpSocket->write(block);
                //login success, update database
                db->updateUserLogStat(id, "1");
                db->updateUserIp(id,tcpSocket->peerAddress().toString());
            }

        }
    }

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

 

   

 

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

 

12点多了晚安~

  
 

 


     

作者:yiyaaixuexi 发表于2011-8-3 0:38:26 原文链接
阅读:14269 评论:138 查看评论
posted @ 2011-08-02 16:38  .net|C#|js|jquery|css|div|html  阅读(286)  评论(0编辑  收藏  举报