Qt如何使用qt命名空间

下次自动登录
现在的位置:
& 综合 & 正文
QT_BEGIN_NAMESPACE 和 QT_BEGIN_NAMESPACE
比较好的解释:
QT_BEGIN_NAMESPACE其实就是个宏,以前Qt4是没有Qt命名空间的,后来才加上的,编译Qt源码时会有选项,是否将这些类放到专用的Qt命名空间内,默认是没有的。这就出来问题了,为了统一,如果你的在默认没有Qt命名空间的SDK中编译,那你就不用在前置声明下面这些类的时候加上命名空间,但如果你在有Qt命名空间的SDK中编译,那就得加上命名空间了,为了屏蔽这个差异,使得你的源码能在这两种情况下都进行编译,Qt提供了QT_BEGIN_NAMESPACE宏,这样开发者就省得自己来用或宏进行处理了。
class QDialogButtonB
class QPushB
class QSqlTableM
至于说加快编译速度什么的,那是上述三个类的前置声明的作用,这是与Qt无关的(也即与QT_BEGIN_NAMESPACE宏无关)。如果你在头文件中只用到一些类的指针(而非实现),那么就可以不包含这些类的头文件,而只使用上面形式的类型前置声明,而在具体实现时才包含入上面这些类型的头文件。如此,头文件里所包含的头文件减少了,那么使用到这个头文件的程序就能包含更少的内容,而不是每次都包含很多头文件,解析起来都耗时。
--来自qtcn
&&&&推荐文章:
【上篇】【下篇】Qt如何使用命名空间,急求助
[问题点数:30分]
Qt如何使用命名空间,急求助
[问题点数:30分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年11月 Linux/Unix社区大版内专家分月排行榜第二2011年8月 Linux/Unix社区大版内专家分月排行榜第二2008年10月 C/C++大版内专家分月排行榜第二
2012年8月 Linux/Unix社区大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。Qt5qml官方Demo解析集1——Fortune Server/Client | qml | 稀泥蟹
& Qt5qml官方Demo解析集1——Fortune Server/Client
Qt5qml官方Demo解析集1——Fortune Server/Client
最近发觉学习Qt官方demo的好处越来越多,除了了解特定模块与类的用法,更能学习一些平时注意不到的小的编程技巧,以及优秀的编程习惯,总之,好处多多啦~
考虑到学习是个往复的过程,好记性不如烂笔头嘛,勤快点记下来免得日后忘记,也方便官方demo不在身边的话也能随时取得到,最后也为学习Qt的网友们做个浅显的参考。
所以打算争取将Qt5官方demo一一解析在此博客中。做此工作本意也是为了学习,能力所限,不妥之处还请各位多多指正~~以上,则是为Qt5官方Demo解析集创作的缘由。
/****************************************************************************************************************/
先从一个简单的network例子开始吧~
Fortune Server/Client 由两个程序构成&(Fortune Server Example)和(Fortune Client Example)。也就是我们所说的服务器和客户端
首先看下Qt对这个例子的介绍:Demonstrates how to create a server for a network service.
fortuneserver一共就3个文件,先来看Server的main.cpp:
#include&&QApplication&&&
#include&&QtCore&&&
#include&&stdlib.h&&&
#include&“server.h”&&
int&main(int&argc,&char&*argv[])&&
&&&&QApplication&app(argc,&argv);&&
&&&&Server&&&
&&&&server.show();&&
&&&&qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));&&
&&&&return&app.exec();&&
前面一大段是版权所有,开源许可之类的东西,我们就不管它了。这段代码唯一值得说的就是13行,可以理解为随机种子的初始化。记得使用它要#include &stdlib.h&
#ifndef&SERVER_H&&
#define&SERVER_H&&
#include&&QDialog&&&
QT_BEGIN_NAMESPACE&&
class&QL&&
class&QPushB&&
class&QTcpS&&
class&QNetworkS&&
QT_END_NAMESPACE&&
class&Server&:&public&QDialog&&
&&&&Q_OBJECT&&
&&&&Server(QWidget&*parent&=&0);&&
private&slots:&&
&&&&void&sessionOpened();&&
&&&&void&sendFortune();&&
private:&&
&&&&QLabel&*statusL&&
&&&&QPushButton&*quitB&&
&&&&QTcpServer&*tcpS&&
&&&&QStringList&&&
&&&&QNetworkSession&*networkS&&
QT_BEGIN_NAMESPACE和QT_END_NAMESPACE宏在源代码中是这样定义的:
# define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {
# define QT_END_NAMESPACE }
也就是说,如果你定义以下内容:
QT_BEGIN_NAMESPACE
class&QListV
QT_END_NAMESPACE
那么,在编译时就会变成这样:
namespace&QT_NAMESPACE {
&&&&class&QListV
仅当在编译Qt时,加上-qtnamespace选项时,这两个宏才会有作用,这时,Qt作为第三方库,要使用用户自定义的命名空间来访问Qt中的类,如QListView *view = new QT_NAMESPACE::QListView
如果我们只需要声明类的指针或者引用,使用前向声明而不是#include可以减少头文件之间的依赖。这在大型项目中减少编译时间是很必要的。
QTcpServer *tcpS&
QNetworkSession *networkS
这是最核心的两个类声明了,前者提供了一个基于TCP的服务器,后者则提供了系统网络接口控制。
好了,来看重头Server.cpp,为了简明部分注释就直接加注释在后面了
#include&&QtWidgets&&&
#include&&QtNetwork&&&
#include&&stdlib.h&&&
#include&“server.h”&&
Server::Server(QWidget&*parent)&&
:&&&QDialog(parent),&tcpServer(0),&networkSession(0)&&&
&&&&statusLabel&=&new&QL&&
&&&&quitButton&=&new&QPushButton(tr(“Quit”));&&
&&&&quitButton-&setAutoDefault(false);&&
&&&&QNetworkConfigurationManager&&&
&&&&if&(manager.capabilities()&&&QNetworkConfigurationManager::NetworkSessionRequired)&{&&&&
&&&&&&&&QSettings&settings(QSettings::UserScope,&QLatin1String(“QtProject”));&&&&
&&&&&&&&settings.beginGroup(QLatin1String(“QtNetwork”));&&
&&&&&&&&const&QString&id&=&settings.value(QLatin1String(“DefaultNetworkConfiguration”)).toString();&&
&&&&&&&&settings.endGroup();&&
&&&&&&&&QNetworkConfiguration&config&=&manager.configurationFromIdentifier(id);&&
&&&&&&&&if&((config.state()&&&QNetworkConfiguration::Discovered)&!=&&
&&&&&&&&&&&&QNetworkConfiguration::Discovered)&{&&
&&&&&&&&&&&&config&=&manager.defaultConfiguration();&&&
&&&&&&&&}&&
&&&&&&&&networkSession&=&new&QNetworkSession(config,&this);&&&
&&&&&&&&connect(networkSession,&SIGNAL(opened()),&this,&SLOT(sessionOpened()));&&
&&&&&&&&statusLabel-&setText(tr(“Opening&network&session.”));&&
&&&&&&&&networkSession-&open();&&
&&&&}&else&{&&
&&&&&&&&sessionOpened();&&
&&&&&&&&fortunes&&&&tr(“You’ve&been&leading&a&dog’s&life.&Stay&off&the&furniture.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“You’ve&got&to&think&about&tomorrow.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“You&will&be&surprised&by&a&loud&noise.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“You&will&feel&hungry&again&in&another&hour.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“You&might&have&mail.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“You&cannot&kill&time&without&injuring&eternity.”)&&
&&&&&&&&&&&&&&&&&&&&tr(“Computers&are&not&intelligent.&They&only&think&they&are.”);&&
&&&&&&&&connect(quitButton,&SIGNAL(clicked()),&this,&SLOT(close()));&&
&&&&&&&&connect(tcpServer,&SIGNAL(newConnection()),&this,&SLOT(sendFortune()));&&
&&&&&&&&QHBoxLayout&*buttonLayout&=&new&QHBoxL&&
&&&&&&&&buttonLayout-&addStretch(1);&&
&&&&&&&&buttonLayout-&addWidget(quitButton);&&
&&&&&&&&buttonLayout-&addStretch(1);&&
&&&&&&&&QVBoxLayout&*mainLayout&=&new&QVBoxL&&
&&&&&&&&mainLayout-&addWidget(statusLabel);&&
&&&&&&&&mainLayout-&addLayout(buttonLayout);&&
&&&&&&&&setLayout(mainLayout);&&
&&&&&&&&setWindowTitle(tr(“Fortune&Server”));&&
void&Server::sessionOpened()&&
&&&&if&(networkSession)&{&&
&&&&&&&&QNetworkConfiguration&config&=&networkSession-&configuration();&&
&&&&&&&&QString&&&
&&&&&&&&if&(config.type()&==&QNetworkConfiguration::UserChoice)&&
&&&&&&&&&&&&id&=&networkSession-&sessionProperty(QLatin1String(“UserChoiceConfiguration”)).toString();&&
&&&&&&&&else&&
&&&&&&&&&&&&id&=&config.identifier();&&
&&&&&&&&QSettings&settings(QSettings::UserScope,&QLatin1String(“QtProject”));&&
&&&&&&&&settings.beginGroup(QLatin1String(“QtNetwork”));&&
&&&&&&&&settings.setValue(QLatin1String(“DefaultNetworkConfiguration”),&id);&&
&&&&&&&&settings.endGroup();&&
&&&&tcpServer&=&new&QTcpServer(this);&&
&&&&if&(!tcpServer-&listen())&{&&&&
&&&&&&&&QMessageBox::critical(this,&tr(“Fortune&Server”),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tr(“Unable&to&start&the&server:&%1.”)&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.arg(tcpServer-&errorString()));&&
&&&&&&&&close();&&
&&&&&&&&return;&&
&&&&QString&ipA&&
&&&&QList&QHostAddress&&ipAddressesList&=&QNetworkInterface::allAddresses();&&&
&&&&for&(int&i&=&0;&i&&&ipAddressesList.size();&++i)&{&&
&&&&&&&&if&(ipAddressesList.at(i)&!=&QHostAddress::LocalHost&&&&&
&&&&&&&&&&&&ipAddressesList.at(i).toIPv4Address())&{&&&
&&&&&&&&&&&&ipAddress&=&ipAddressesList.at(i).toString();&&
&&&&&&&&&&&&break;&&
&&&&&&&&}&&
&&&&if&(ipAddress.isEmpty())&&
&&&&&&&&ipAddress&=&QHostAddress(QHostAddress::LocalHost).toString();&&
&&&&statusLabel-&setText(tr(“The&server&is&running&on\n\nIP:&%1\nport:&%2\n\n”&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&“Run&the&Fortune&Client&example&now.”)&&
&&&&&&&&&&&&&&&&&&&&&&&&&.arg(ipAddress).arg(tcpServer-&serverPort()));&&&
void&Server::sendFortune()&&
&&&&QByteArray&&&
&&&&QDataStream&out(&block,&QIODevice::WriteOnly);&&&
&&&&out.setVersion(QDataStream::Qt_4_0);&&&
&&&&out&&&&(quint16)0;&&&
&&&&out&&&&fortunes.at(qrand()&%&fortunes.size());&&&
&&&&out.device()-&seek(0);&&
&&&&out&&&&(quint16)(block.size()&–&sizeof(quint16));&&&
&&&&QTcpSocket&*clientConnection&=&tcpServer-&nextPendingConnection();&&
&&&&connect(clientConnection,&SIGNAL(disconnected()),&&&
&&&&&&&&&&&&clientConnection,&SLOT(deleteLater()));&&
&&&&clientConnection-&write(block);&&&
&&&&clientConnection-&disconnectFromHost();&&&
第一点,很多地方都有讲这个out.setVersion(QDataStream::Qt_4_0),就说编码统一什么的,让人听的一头雾水。明确的说,为了适应新的功能,一些Qt类的数据类的序列化格式已经在一些新版本的Qt发生了改变。也就是说,如果基于Qt5.2的数据发送到Qt4.0的客户机上,很可能他取出的数据与你发送的数据不同。这样就需要规定一个统一的数据流格式,这里将版本设置为Qt_4_0,也就是以4.0版本的数据流序列化格式发送数据。客户机也只有设置了相同的版本才能保证数据的准确解析。
第二点,为了保证在客户端能接收到完整的文件,我们都在数据流的最开始写入完整文件的大小信息,这样客户端就可以根据大小信息来判断是否接受到了完整的文件。而在服务器端,我们在发送数据时就要首先发送实际文件的大小信息,但是,文件的大小一开始是无法预知的,所以我们先使用了out&&(quint16) 0;在block的开始添加了一个quint16大小的空间,也就是两字节的空间,它用于后面放置文件的大小信息。
第三点,当文件输入完成后我们在使用out.device()-&seek(0);返回到block的开始,加入实际的文件大小信息,也就是后面的代码,它是实际文件的大小:out&&(quint16) (block.size() – sizeof(quint16));
好了,服务端大致这些,实际就我们一般的使用中,使用默认的网络配置就可以了,所以核心程序还是很简单的。
下面来看客户端代码吧~与fortuneServer一样,fortuneClient中也只有3个文件,main.cpp保持了Qt一贯的简约风格,我们就跳过它来看client.h:
#ifndef&CLIENT_H&&
#define&CLIENT_H&&
#include&&QDialog&&&
#include&&QTcpSocket&&&
QT_BEGIN_NAMESPACE&&
class&QComboB&&
class&QDialogButtonB&&
class&QL&&
class&QLineE&&
class&QPushB&&
class&QTcpS&&
class&QNetworkS&&
QT_END_NAMESPACE&&
class&Client&:&public&QDialog&&
&&&&Q_OBJECT&&
&&&&Client(QWidget&*parent&=&0);&&
private&slots:&&
&&&&void&requestNewFortune();&&
&&&&void&readFortune();&&
&&&&void&displayError(QAbstractSocket::SocketError&socketError);&&&
&&&&void&enableGetFortuneButton();&&
&&&&void&sessionOpened();&&
private:&&
&&&&QLabel&*hostL&&
&&&&QLabel&*portL&&
&&&&QComboBox&*hostC&&
&&&&QLineEdit&*portLineE&&
&&&&QLabel&*statusL&&
&&&&QPushButton&*getFortuneB&&
&&&&QPushButton&*quitB&&
&&&&QDialogButtonBox&*buttonB&&
&&&&QTcpSocket&*tcpS&&
&&&&QString&currentF&&
&&&&quint16&blockS&&&
&&&&QNetworkSession&*networkS&&
一般来讲privat,private slots放在最下面,因为被查看的最少。
既然说的QTcpSocket,需要介绍一下它的两种网络编程的方式:
第一种是异步(non-blocking)方法。业务调度和执行时控制返回到Qt的事件循环。当操作完成时,QTcpSocket发出信号。例如,QTcpSocket::connectToHost()是立即返回的,而当连接已经建立后,QTcpSocket再发出connected()信号表明自己已成功连接。&
第二种是同步(blocking)的方法。在非图形用户界面和多线程应用程序,可以调用WAITFOR…()函数(例如,QTcpSocket:: waitForConnected())暂停直到操作完成。&
在这个Demo中,是以异步方式建立的网络。Blocking Fortune Example中使用了同步的方法,这个下次来看。
client.cpp:
#include&&QtWidgets&&&
#include&&QtNetwork&&&
#include&“client.h”&&
Client::Client(QWidget&*parent)&&
:&&&QDialog(parent),&networkSession(0)&&
&&&&hostLabel&=&new&QLabel(tr(“&Server&name:”));&&
&&&&portLabel&=&new&QLabel(tr(“S&erver&port:”));&&
&&&&hostCombo&=&new&QComboB&&
&&&&hostCombo-&setEditable(true);&&
&&&&QString&name&=&QHostInfo::localHostName();&&&
&&&&if&(!name.isEmpty())&{&&
&&&&&&&&hostCombo-&addItem(name);&&
&&&&&&&&QString&domain&=&QHostInfo::localDomainName();&&&
&&&&&&&&if&(!domain.isEmpty())&&
&&&&&&&&&&&&hostCombo-&addItem(name&+&QChar(‘.’)&+&domain);&&
&&&&if&(name&!=&QString(“localhost”))&&
&&&&&&&&hostCombo-&addItem(QString(“localhost”));&&
&&&&QList&QHostAddress&&ipAddressesList&=&QNetworkInterface::allAddresses();&&
&&&&for&(int&i&=&0;&i&&&ipAddressesList.size();&++i)&{&第(1)点&&
&&&&&&&&if&(!ipAddressesList.at(i).isLoopback())&&
&&&&&&&&&&&&hostCombo-&addItem(ipAddressesList.at(i).toString());&&
&&&&for&(int&i&=&0;&i&&&ipAddressesList.size();&++i)&{&第(2)点&&
&&&&&&&&if&(ipAddressesList.at(i).isLoopback())&&
&&&&&&&&&&&&hostCombo-&addItem(ipAddressesList.at(i).toString());&&
&&&&portLineEdit&=&new&QLineE&&
&&&&portLineEdit-&setValidator(new&QIntValidator(1,&65535,&this));&&&
&&&&hostLabel-&setBuddy(hostCombo);&&
&&&&portLabel-&setBuddy(portLineEdit);&&
&&&&statusLabel&=&new&QLabel(tr(“This&examples&requires&that&you&run&the&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&“Fortune&Server&example&as&well.”));&&
&&&&getFortuneButton&=&new&QPushButton(tr(“Get&Fortune”));&&
&&&&getFortuneButton-&setDefault(true);&&&
&&&&getFortuneButton-&setEnabled(false);&&
&&&&quitButton&=&new&QPushButton(tr(“Quit”));&&
&&&&buttonBox&=&new&QDialogButtonB&&&
&&&&buttonBox-&addButton(getFortuneButton,&QDialogButtonBox::ActionRole);&&
&&&&buttonBox-&addButton(quitButton,&QDialogButtonBox::RejectRole);&&
&&&&tcpSocket&=&new&QTcpSocket(this);&&
&&&&connect(hostCombo,&SIGNAL(editTextChanged(QString)),&&
&&&&&&&&&&&&this,&SLOT(enableGetFortuneButton()));&&
&&&&connect(portLineEdit,&SIGNAL(textChanged(QString)),&&
&&&&&&&&&&&&this,&SLOT(enableGetFortuneButton()));&&
&&&&connect(getFortuneButton,&SIGNAL(clicked()),&&
&&&&&&&&&&&&this,&SLOT(requestNewFortune()));&&
&&&&connect(quitButton,&SIGNAL(clicked()),&this,&SLOT(close()));&&
&&&&connect(tcpSocket,&SIGNAL(readyRead()),&this,&SLOT(readFortune()));&&
&&&&connect(tcpSocket,&SIGNAL(error(QAbstractSocket::SocketError)),&&
&&&&&&&&&&&&this,&SLOT(displayError(QAbstractSocket::SocketError)));&&
&&&&QGridLayout&*mainLayout&=&new&QGridL&&
&&&&mainLayout-&addWidget(hostLabel,&0,&0);&&
&&&&mainLayout-&addWidget(hostCombo,&0,&1);&&
&&&&mainLayout-&addWidget(portLabel,&1,&0);&&
&&&&mainLayout-&addWidget(portLineEdit,&1,&1);&&
&&&&mainLayout-&addWidget(statusLabel,&2,&0,&1,&2);&&&
&&&&mainLayout-&addWidget(buttonBox,&3,&0,&1,&2);&&
&&&&setLayout(mainLayout);&&
&&&&setWindowTitle(tr(“Fortune&Client”));&&
&&&&portLineEdit-&setFocus();&&
&&&&QNetworkConfigurationManager&&&&&
&&&&if&(manager.capabilities()&&&QNetworkConfigurationManager::NetworkSessionRequired)&{&&
&&&&&&&&&&
&&&&&&&&QSettings&settings(QSettings::UserScope,&QLatin1String(“QtProject”));&&
&&&&&&&&settings.beginGroup(QLatin1String(“QtNetwork”));&&
&&&&&&&&const&QString&id&=&settings.value(QLatin1String(“DefaultNetworkConfiguration”)).toString();&&
&&&&&&&&settings.endGroup();&&
&&&&&&&&&&
&&&&&&&&QNetworkConfiguration&config&=&manager.configurationFromIdentifier(id);&&
&&&&&&&&if&((config.state()&&&QNetworkConfiguration::Discovered)&!=&&
&&&&&&&&&&&&QNetworkConfiguration::Discovered)&{&&
&&&&&&&&&&&&config&=&manager.defaultConfiguration();&&
&&&&&&&&}&&
&&&&&&&&networkSession&=&new&QNetworkSession(config,&this);&&
&&&&&&&&connect(networkSession,&SIGNAL(opened()),&this,&SLOT(sessionOpened()));&&
&&&&&&&&getFortuneButton-&setEnabled(false);&&
&&&&&&&&statusLabel-&setText(tr(“Opening&network&session.”));&&
&&&&&&&&networkSession-&open();&&
void&Client::requestNewFortune()&&
&&&&getFortuneButton-&setEnabled(false);&&
&&&&blockSize&=&0;&&
&&&&tcpSocket-&abort();&&&
&&&&tcpSocket-&connectToHost(hostCombo-&currentText(),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&portLineEdit-&text().toInt());&&&
void&Client::readFortune()&&
&&&&QDataStream&in(tcpSocket);&&
&&&&in.setVersion(QDataStream::Qt_4_0);&&&
&&&&if&(blockSize&==&0)&{&&
&&&&&&&&if&(tcpSocket-&bytesAvailable()&&&(int)sizeof(quint16))&&
&&&&&&&&&&&&return;&&
&&&&&&&&in&&&&blockS&&&
&&&&if&(tcpSocket-&bytesAvailable()&&&blockSize)&&
&&&&&&&&return;&&&
&&&&QString&nextF&&&
&&&&in&&&&nextF&&&
&&&&if&(nextFortune&==&currentFortune)&{&&&
&&&&&&&&QTimer::singleShot(0,&this,&SLOT(requestNewFortune()));&&&
&&&&&&&&return;&&
&&&&currentFortune&=&nextF&&&
&&&&statusLabel-&setText(currentFortune);&&
&&&&getFortuneButton-&setEnabled(true);&&
void&Client::displayError(QAbstractSocket::SocketError&socketError)&&&
&&&&switch&(socketError)&{&&
&&&&case&QAbstractSocket::RemoteHostClosedError:&&
&&&&&&&&break;&&
&&&&case&QAbstractSocket::HostNotFoundError:&&
&&&&&&&&QMessageBox::information(this,&tr(“Fortune&Client”),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tr(“The&host&was&not&found.&Please&check&the&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&“host&name&and&port&settings.”));&&
&&&&&&&&break;&&
&&&&case&QAbstractSocket::ConnectionRefusedError:&&
&&&&&&&&QMessageBox::information(this,&tr(“Fortune&Client”),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tr(“The&connection&was&refused&by&the&peer.&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&“Make&sure&the&fortune&server&is&running,&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&“and&check&that&the&host&name&and&port&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&“settings&are&correct.”));&&
&&&&&&&&break;&&
&&&&default:&&
&&&&&&&&QMessageBox::information(this,&tr(“Fortune&Client”),&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tr(“The&following&error&occurred:&%1.”)&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.arg(tcpSocket-&errorString()));&&
&&&&getFortuneButton-&setEnabled(true);&&
void&Client::enableGetFortuneButton()&&&
&&&&getFortuneButton-&setEnabled((!networkSession&||&networkSession-&isOpen())&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&!hostCombo-&currentText().isEmpty()&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&!portLineEdit-&text().isEmpty());&&
void&Client::sessionOpened()&&&
&&&&QNetworkConfiguration&config&=&networkSession-&configuration();&&
&&&&QString&&&
&&&&if&(config.type()&==&QNetworkConfiguration::UserChoice)&&
&&&&&&&&id&=&networkSession-&sessionProperty(QLatin1String(“UserChoiceConfiguration”)).toString();&&
&&&&else&&
&&&&&&&&id&=&config.identifier();&&
&&&&QSettings&settings(QSettings::UserScope,&QLatin1String(“QtProject”));&&
&&&&settings.beginGroup(QLatin1String(“QtNetwork”));&&
&&&&settings.setValue(QLatin1String(“DefaultNetworkConfiguration”),&id);&&
&&&&settings.endGroup();&&
&&&&statusLabel-&setText(tr(“This&examples&requires&that&you&run&the&“&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&“Fortune&Server&example&as&well.”));&&
&&&&enableGetFortuneButton();&&
第一点,注意下面两个if 只有一个 ! 的区别。首先添加了环回网路,在我的机子上测试为192.168.1.106、192.168.23.1、192.168.19.1(均属于本地局域网) &&
& & & & & &&
第二点,添加了环回网路,地址为127.0.0.1(Windows下的虚拟接口,永不会down~)
第三点,这点很关键,实际上,尤其在慢速网络中,TCP基于数据流的发送方式会使客户端在一次接收中无法收到一整包的数据。那么,程序在判断接收到的数据长度小于队首的数值时,说明这包数据并不完整,不过没有关系,程序直接返回,等待接下来的片段包,而QTcpSocket会将这些片段缓存,当收到数据长度等于队首长度数值时,再将这些缓存数据全部读出。这也是为什么我们在Server端加入数据长度帧的原因所在。
好了,Fortune Server/Client例程大概就这些~看起来代码很长,其实真正用在发送接收的也不过几句话而已。当然我们自己在做项目的时候也应该像demo一样把各种可能的异常尽量加在处理函数中,这对程序的健壮性是有好处的~
Posted on 12月05日
Posted on 07月31日
Posted on 11月20日
Posted on 09月20日
半夜睡不着,爬起床来走到客厅抽支烟,发现一只蟑螂,于是跟它聊了很长时间,把我对人生的看法,对社会有些现象的不爽,生活的压力,调试遇到的bug,压榨似的发泄给它听,烟抽完了,于是我狠狠一脚踩死了它,没办法,它知道的太多了,压力会大。
文章总数:255篇
评论总数:32条
页面总数:0 个
分类总数:33个
标签总数:486个
运行天数:17052 天

我要回帖

更多关于 如何使用qt 的文章

 

随机推荐