具体如下代码,不赘述
#ifndef WEBTIMEGET_H
#define WEBTIMEGET_H
#include <QString>
#include <QVector>
#include <QObject>
#include <QDateTime>
#include <QtNetwork/QUdpSocket>
class webTimeGetter : public QObject
{
Q_OBJECT
public:
webTimeGetter();
virtual ~webTimeGetter();
public slots:
void readingData();
void connectSucess();
void tryGet();
private:
QVector<QString> hostList;
QUdpSocket* udpsocket;
QDateTime time;
};
#endif
//! ccsdu2004
#include <iostream>
#include "webTimeGetter.h"
webTimeGetter::webTimeGetter()
{
hostList.push_back("time.windows.com");
hostList.push_back("time.nist.gov");
udpsocket = new QUdpSocket(this);
connect(udpsocket,SIGNAL(connected()),this,SLOT(connectSucess()));
connect(udpsocket,SIGNAL(readyRead()),this,SLOT(readingData()));
}
webTimeGetter::~webTimeGetter()
{
}
void webTimeGetter::readingData()
{
QByteArray newTime;
QDateTime epoch(QDate(1900, 1, 1));
QDateTime unixStart(QDate(1970, 1, 1));
do
{
newTime.resize(udpsocket->pendingDatagramSize());
udpsocket->read(newTime.data(), newTime.size());
}while(udpsocket->hasPendingDatagrams());
QByteArray TransmitTimeStamp ;
TransmitTimeStamp=newTime.right(8);
quint32 seconds=TransmitTimeStamp[0];
quint8 temp=0;
for(int j=1;j<=3;j++)
{
seconds=seconds<<8;
temp=TransmitTimeStamp[j];
seconds=seconds+temp;
}
time.setTime_t(seconds-epoch.secsTo(unixStart));
std::cout<<time.date().year()<<std::endl;
std::cout<<time.date().month()<<std::endl;
std::cout<<time.date().day()<<std::endl;
std::cout<<time.time().hour()<<std::endl;
std::cout<<time.time().minute()<<std::endl;
udpsocket->disconnectFromHost();
udpsocket->close();
}
void webTimeGetter::connectSucess()
{
qint8 LI=0;
qint8 VN=3;
qint8 MODE=3;
qint8 STRATUM=0;
qint8 POLL=4;
qint8 PREC=-6;
QDateTime epoch(QDate(1900,1,1));
qint32 second=quint32(epoch.secsTo(QDateTime::currentDateTime()));
qint32 temp=0;
QByteArray timeRequest(48, 0);
timeRequest[0]=(LI <<6) | (VN <<3) | (MODE);
timeRequest[1]=STRATUM;
timeRequest[2]=POLL;
timeRequest[3]=PREC & 0xff;
timeRequest[5]=1;
timeRequest[9]=1;
timeRequest[40]=(temp=(second&0xff000000)>>24);
temp=0;
timeRequest[41]=(temp=(second&0x00ff0000)>>16);
temp=0;
timeRequest[42]=(temp=(second&0x0000ff00)>>8);
temp=0;
timeRequest[43]=((second&0x000000ff));
udpsocket->flush();
udpsocket->write(timeRequest);
udpsocket->flush();
}
void webTimeGetter::tryGet()
{
udpsocket->connectToHost(hostList.at(0),123);
}
有2种办法
第一种是
针对输入的数据n bite数据A,B比如short类型
If both A and B are negative Y = A + B - (A * B / (-(2 pow(n-1) -1)))
Else Y = A + B - (A * B / (2 pow(n-1))
另外一种办法是采用时间片交替的方式
Microsoft Visual Studio 2005 Team Suite 简体中文版 序列号 注册码
序列号:KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J (可用)
添加/删除程序 - Microsoft Visual Studio 2005 Team Suite 简体中文版 - 卸载 - 下一步 - KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J - 升级。
typedef struct RingBuffer RingBuffer;
RingBuffer* RingBufferCreate(int sizeOf,int length);
void RingBufferDestroy(RingBuffer* ring);
int RingBufferWrite(RingBuffer* ring,const char* data,int len);
int RingBufferRead(RingBuffer* ring,char* data,int len);
struct RingBuffer
{
char* mem;
int sizeOf;
int length;
int writePos;
int full;
};
RingBuffer* RingBufferCreate(int sizeOf,int length)
{
RingBuffer *ring = (RingBuffer*)calloc(1,sizeof(*ring));
if(ring)
{
ring->sizeOf = sizeOf;
ring->length = length;
ring->writePos = 0;
ring->full = 0;
ring->mem = (char*)malloc(ring->length * ring->sizeOf);
if(!ring->mem)
{
free(ring);
ring = 0;
}
}
return ring;
}
void RingBufferDestroy(RingBuffer* ring)
{
if(ring)
{
free(ring->mem);
free(ring);
}
}
int RingBufferRead(RingBuffer* ring,char* data,int len)
{
if(ring->full == 1)
{
if(len > ring->length)
len = ring->length;
memcpy(data,ring->mem,len*ring->sizeOf);
ring->full = 0;
}
if(ring->writePos < len)
{
ring->full = 0;
int ret = ring->writePos;
ring->writePos = 0;
memcpy(data,ring->mem,ring->writePos*ring->sizeOf);
return ret;
}
else
{
ring->full = 0;
memcpy(data,ring->mem,len*ring->sizeOf);
ring->writePos -= len;
memcpy(ring->mem,ring->mem + len*ring->sizeOf,ring->writePos*ring->sizeOf);
return len;
}
}
int RingBufferWrite(RingBuffer* ring,const char* data,int len)
{
if(len + ring->writePos > ring->length)
ring->full = 1;
int ret = len >= ring->length ? ring->length : len;
if(len >= ring->length)
{
memcpy(ring->mem,data + (ring->length-ring->length%len)*ring->sizeOf,ring->length*ring->sizeOf);
ring->writePos = ring->length;
}
else if(len + ring->writePos <= ring->length)
{
memcpy(ring->mem + ring->writePos*ring->sizeOf,data,len*ring->sizeOf);
ring->writePos += len;
}
else
{
memcpy(ring->mem,ring->mem + (len + ring->writePos - ring->length)*ring->sizeOf,(len + ring->writePos - ring->length)*ring->sizeOf);
memcpy(ring->mem + (len + ring->writePos - ring->length)*ring->sizeOf,data,len*ring->sizeOf);
ring->writePos = ring->length;
}
return ret;
}
简单说明 乱码原因
QURL的2次连续编码
修改方式:
QUrl encode(const QString& istr)
{
QByteArray data;
data.append(istr);
return QUrl::fromEncoded(data);
}
一个小例子:
class libcurlParser : public QThread
{
Q_OBJECT
public:
static size_t process(void* buffer,size_t size,size_t n,void *user);
QString html;
public:
libcurlParser(QObject *parent= 0);
~libcurlParser();
public:
void execute(const QString& url);
public slots:
void finishSlot();
void timeOut();
signals:
void finish();
protected:
void run();
private:
CURL* curl;
};
size_t libcurlParser::process(void* buffer,size_t size,size_t n,void *user)
{
libcurlParser* parser = (libcurlParser*)user;
parser->html += (char*)buffer;
return size*n;
}
libcurlParser::libcurlParser(QObject *parent)
: QThread(parent)
{
connect(this,SIGNAL(finish()),this,SLOT(finishSlot()));
curl = curl_easy_init();
}
libcurlParser::~libcurlParser()
{
curl_easy_cleanup(curl);
}
void libcurlParser::execute(const QString& url)
{
html.clear();
curl_easy_setopt(curl,CURLOPT_URL,url.toAscii().data());
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,&process);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,this);
start();
}
void libcurlParser::run()
{
CURLcode code = curl_easy_perform(curl);
std::cout<<"exe:"<<"code"<<std::endl;
emit finish();
//std::cout<<curl_easy_strerror(code)<<std::endl;
//QTimer::singleShot(0, this, SLOT(timeOut()));
//exec();
}
void libcurlParser::finishSlot()
{
std::cout<<"finishSlot()"<<std::endl;
QFile file("htm.htm");
file.open(QIODevice::WriteOnly);
file.write(html.toLatin1());
file.close();
}
void libcurlParser::timeOut()
{
emit finish();
}
有时候程序需要显示二个排列在一起的顶级窗体,并且拖动主窗体次窗体也跟着移动
其实现如下:
1.保持窗体并列显示在一起
QPoint pos = this->pos();
QSize size = this->size();
int x = pos.x() + size.width() + 8;
int y = pos.y();
widget1->move(x,y);
2.移动主窗体,次窗体也跟着移动
这个需要重载函数moveEvent
void window::moveEvent(QMoveEvent *event)
{
onMove();
QWidget::moveEvent(event);
}
QT中使用信号和槽的注意事项
只能使用本对象的信号,不能使用基类的
但是可以使用基类的槽,而不一定要使用本对象的
违反的话 可能会出现导致程序退出的问题
在QThread中使用QNetworkAccessManager,需要注意的是:
在run()函数中需要调用exec()
这样才能保证线程消息队列不退出
然后在必要的地方调用quit即可退出
在QLineEidt上按回车会发送一个消息returnPressed();
接受此消息即可