poco库应用框架

2024-05-06 16:48
文章标签 应用 框架 poco

本文主要是介绍poco库应用框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Net

1. http框架

1.1 http下载文件

#include "StdAfx.h"
#include <Winsock2.h>
#include <stdio.h>
#include "Poco/URIStreamOpener.h"
#include "Poco/StreamCopier.h"
#include "Poco/Path.h"
#include "Poco/URI.h"
#include "Poco/Exception.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/FTPStreamFactory.h"
#include "Poco/UUID.h"
#include "Poco/UUIDGenerator.h"
#include <memory>
#include <iostream>
#include <string>
#include <fstream>

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;
using Poco::URIStreamOpener;
using Poco::StreamCopier;
using Poco::Path;
using Poco::URI;
using Poco::Exception;
using Poco::Net::HTTPStreamFactory;
using Poco::Net::FTPStreamFactory;
using Poco::UUID;
using Poco::UUIDGenerator;
using namespace std;
using std::ostream;

vector<std::string> vs; 
//清除每一行末尾的 多余字符
void clean_string(char *str)
{
char *start = str - 1;
char *end = str;
char *p = str;
while(*p)
{
switch(*p)
{
case ' ':
case '\r':
case '\n':
{
if(start + 1==p)
start = p;
}
break;
default:
break;
}
++p;
}
//现在来到了字符串的尾部 反向向前
--p;
++start;
if(*start == 0)
{
//已经到字符串的末尾了 
*str = 0 ;
return;
}
end = p + 1;
while(p > start)
{
 
switch(*p)
{
case ' ':
case '\r':
case '\n':
{
if(end - 1 == p)
end = p;
}
break;
default:
break;
}
--p;
}
memmove(str,start,end-start);
*(str + (int)end - (int)start) = 0;
}


//获取文件下载列表
int downList(URI uri){


try
{
//URI uri(argv[0]);
//URI uri("http://192.168.30.109:8080/logapp/downlist.txt");
//URI uri("http://192.168.55.109:8080/logapp/downlist.zip");
std::auto_ptr<std::istream> pStr(URIStreamOpener::defaultOpener().open(uri));
//StreamCopier::copyStream(*pStr.get(), std::cout);
 
char str[100]= {0};

while(!pStr.get()->eof()) {
if(pStr.get()->getline(str, 100)){

std::cout<< str << endl;
std::cout<< "2222" << endl;
//std::string strV= str;
clean_string(str);
vs.push_back(str);


}
}
 
}
catch (Exception& exc)
{
std::cerr << exc.displayText() << std::endl;
//system("pause");
return 1;
}
return 0;
}
//下载文件
int downFile(vector<std::string> vs){
try
{
//std:string xx = "http://192.168.30.109:8080/logapp/downlist.zip";//
//string xx2 = vs[0];
//printf("%s", xx2.c_str());
//int s = strcmp(xx.c_str(), xx2.c_str());
//URI uri(xx2);
//URI uri2("http://192.168.30.109:8080/logapp/downlist.zip");
for(vector<int>::size_type i = 0; i<vs.size() ; i++){
URI uri(vs[i]);
std::string filePath = uri.getPath();
string filename = filePath.substr(8);
std::auto_ptr<std::istream> pStr(URIStreamOpener::defaultOpener().open(uri));
//ofstream ds("D:\\adfile.zip");
UUIDGenerator *uuidG = new UUIDGenerator();
UUID uuid = uuidG->createOne();
ofstream ds("D:\\"+uuid.toString()+".zip");
//FILE *file = fopen(to "wb");
if(ds!= NULL){
//fprintf( file, "Hello %s\n", *pStr.get() );
StreamCopier::copyStream(*pStr.get(),ds);
}
}

//StreamCopier::copyStream(*pStr.get(), std::cout);



/*std::string str ;
if(getline( *pStr.get(), str )){
std::cout<< str << endl;
} */
}
catch (Exception& exc)
{
std::cerr << exc.displayText() << std::endl;
//system("pause");
return 1;
}
}


int main(int argc, char** argv)
{
URI uri("http://192.168.30.109:8080/logapp/downlist.txt");
HTTPStreamFactory::registerFactory();
FTPStreamFactory::registerFactory();

if (argc != 2)
{
Path p(argv[0]);
std::cerr << "usage: " << p.getBaseName() << " <uri>" << std::endl;
std::cerr << "       Download <uri> to standard output." << std::endl;
std::cerr << "       Works with http, ftp and file URIs." << std::endl;
//system("pause");
//return 1;

downList( uri);
downFile( vs);
system("pause");
return 0;
}



2. tcpserver框架

客户端下载:

#include "StdAfx.h"
#include <Winsock2.h>
#include <stdio.h>
#include <Poco/String.h>
#include <Poco/Zip/ZipStream.h>
#include <Poco/Path.h>
#include <Poco/DateTime.h>
#include <iostream > 
#include <fstream > 
#include <Poco/Zip/Decompress.h>
#include <Poco/UnicodeConverter.h>
#include <Poco/Net/Net.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTMLForm.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/String.h>
#include <Poco/UnicodeConverter.h>
#include <Poco/Net/SocketStream.h>
#include <windows.h> 
#include <stdio.h> 
#include "json/json.h"
#include <vector>
#include <io.h>
using Poco::trim;
using Poco::trimLeft;
using Poco::trimRight;
using Poco::trimRightInPlace;
using Poco::Zip::ZipInputStream;
using Poco::PathSyntaxException;
using std::ifstream;
using Poco::Zip::Decompress;
using Poco::UnicodeConverter;
using namespace Poco::Net;
using namespace std;
using  Poco::StreamCopier;

using Poco::Net::SocketAddress;
using Poco::Net::StreamSocket;

#define BUFFER_SIZE 1024

int UTF82GBK(const char *szUtf8,char *szGbk,int Len);
//void sendBytes(StreamSocket socket,char buffer[] );
//void sendBytes(StreamSocket socket,char buffer[] ,char buffer1[BUFFER_SIZE]);
//void readBytes(StreamSocket socket,char buffer[]);
#pragma pack (4)
 struct PInfo{
char type;
int filelength;
int  readystatus;
char filename[1024] ;
} ;

vector<std::string> getList( vector<std::string> files){
Poco::Net::SocketAddress sa("www.ssd.com",9911);
Poco::Net::StreamSocket socket(sa);
struct PInfo pi = {0,0,0,0};
socket.sendBytes((char*)&pi,sizeof(pi));
char buf[1024];
int len = socket.receiveBytes(buf, 1024);
PInfo* recvPi = (PInfo*)buf;
char* strjson = recvPi->filename;
Json::Reader reader;
Json::Value root;

if(reader.parse(strjson,root)){
 
int pathnum = root["path"].size();  // 得到"files"的数组个数  
for(int i = 0; i < pathnum; i++)  // 遍历数组  
{  
files.push_back(root["path"][i].asString());

}
}

socket.close();
return files;
}

void getFile(vector<std::string> files){

for(int i = 0; i < files.size(); i++)  // 遍历数组  
{  
 
Poco::Net::SocketAddress sa("www.ssd.com",9911);
Poco::Net::StreamSocket socket(sa);  
PInfo pi;

sprintf(pi.filename,"%s",files[i].c_str());
pi.type =  1;

pi.filelength = 0;
pi.readystatus = 0;
 
socket.sendBytes((char*)&pi,sizeof(pi));

std::string  filepath = "D:\\sample1\\"+files[i];
//std::string  filepath = "D:\\xx.zip";
const char *fpath = filepath.c_str();
FILE *fp = fopen(fpath,"wb");

if(!fp){
printf("打开文件失败!!!");
return ;
}else{
printf("文件已经打开,等待传输...\n");
}
char data[1024];
int j = 0 ;
int totallen = 0;
//int len = socket.receiveBytes(data, 1024);
// PInfo* recvPi = (PInfo*)(data);
// //std::cout << "" << pi->filelength << std::endl;
// int filelength = recvPi->filelength;
// if(filelength>0){

/*PInfo sendPi ;
sendPi.filelength = filelength;
sendPi.readystatus = 1;
sendPi.type = 1;
sprintf(sendPi.filename,"%s",files[i].c_str());
char buf[sizeof(sendPi)];
memcpy(buf, &sendPi, sizeof(buf));
socket.sendBytes(buf,sizeof(buf));*/

while(1){
memset(data,0,1024);  
int len = socket.receiveBytes(data, 1024);
fwrite(data,1,len,fp);
j++;
printf("%d\r\n", len);
totallen=totallen+len;
if(len<=0){  
fclose(fp);
break;
}
/*if(totallen==filelength){

break;
}*/

}
//}
printf("retlen=%d \n",totallen);
socket.close();  
//printf("retlen=%d i=%d\n",totallen,i);
//printf("写入的文件内容为:\n %s\n",data);
}
}
int main(){
char buffer[BUFFER_SIZE];
vector<std::string> files;
//files.push_back("71e1eaba-c894-11e4-b9c7-94de80fb7973.zip");
files = getList(files);
getFile( files);

//WSACleanup();
//system("pause");
return 0;
}


服务器:

#include "StdAfx.h"
#include "json/json.h"
#include <vector>
#include <io.h>
#include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Net/TCPServerParams.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/ServerSocketImpl.h"
#include "Poco/Timestamp.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/Exception.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include <iostream>
#include <io.h>
#include <Windows.h>
#include <WinReg.h>
#include <stdio.h>
 
using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::TCPServer;
using Poco::Timestamp;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using namespace std;

#pragma pack (4)
struct PInfo{
char type;
int filelength;
int  readystatus;
char filename[1024];
};
 
class TimeServerConnection: public TCPServerConnection
/// This class handles all client connections.
///
/// A string with the current date and time is sent back to the client.
{
public:
TimeServerConnection(const StreamSocket& s, const std::string& format): 
TCPServerConnection(s),
_format(format)
{
}
int  GetFileSize(const char *filepath,FILE *file){
//string path = "D:\\m.zip";
//const char *fpath = path.c_str();
//FILE* file = fopen(filepath, "rb");
int size;
if (file)
{
size = filelength(fileno(file));
std::cout<<size<<std::endl;
fclose(file);
}
 
return size ;
}
void getFiles(string path,vector<string>& files){
long hFile = 0;
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo))!=-1){

do  
{  
//如果是目录,迭代之  
//如果不是,加入列表  
if((fileinfo.attrib &  _A_SUBDIR))  
{  
if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)  
getFiles( p.assign(path).append("\\").append(fileinfo.name), files );  
}  
else  
{  
//files.push_back(p.assign(path).append("\\").append(fileinfo.name) );  
files.push_back(fileinfo.name);  
}  
}while(_findnext(hFile, &fileinfo)  == 0);  
_findclose(hFile); 
}
}
void sendList() {


char *filePath = "D:\\sample";

vector<std::string> files;
getFiles(filePath,files);
 
int size = files.size();
//const char* urljson ="{\"url1\":\"71e286fa-c894-11e4-b9c7-94de80fb7973.zip\"\"url1\":\"71e286fa-c894-11e4-b9c7-94de80fb7973.zip\",\"url1\":\"71e286fa-c894-11e4-b9c7-94de80fb7973.zip\"}";
//{path:[\"a.zip\", \"b.zip\"]}
//char* urljson = "{path:[";
std::string strjson = "{\"path\":[";
for(int i=0;i<size;i++){
cout<<files[i].c_str()<<endl;
strjson +="\"";
strjson += files[i].c_str();
strjson +="\"";
if(i<(size-1)){
strjson +=",";
}
}
strjson +="]}";

PInfo pi;
memset(pi.filename, 1024, 0);
pi.type = 0;
sprintf(pi.filename, "%s", strjson.c_str());
char buf[sizeof(pi)];
socket().sendBytes((char*)&pi, sizeof(pi));


return;
}


void sendFile(int n,  char buf[1024]){
if (n > 0){
PInfo* pi = (PInfo*)(buf);
std::cout << "" << socket().address().toString() << std::endl;
 
//socket().sendBytes(buf, n);
std::cout << "" << socket().peerAddress().toString() << std::endl;
std::cout << "" << pi->filelength << std::endl;
std::cout << "" << pi->readystatus << std::endl;

std::string  filepath = "D:\\sample";
std::string  path;
path.assign(filepath).append("\\").append(pi->filename);
const char *fpath = path.c_str();
//if( pi->readystatus==0){
//
// //FILE* fp = fopen(fpath, "rb");
// //int  length = GetFileSize(fpath,fp);
// //  
// //std::cout << "" << length << std::endl;
// //std::cout << "" << pi->filelength << std::endl;
// //PInfo filesizepi;
// //filesizepi.readystatus = 0;
// //filesizepi.filelength = length;
// //memset(filesizepi.filename, 0, 1024);
// //filesizepi.type = 0;
// //
// socket().sendBytes((char*)&pi,sizeof(pi));
// //socket().sendBytes((char*)&filesizepi,sizeof(PInfo));
//  
//}else 
//if( pi->readystatus==1){ 
FILE* fp = fopen(fpath, "rb");
if(!fp){

printf("error!");
return ;
}else{

printf("文件已经打开,等待传输...\n");
}
char data[1024] = {0};
int len = 0;
int i =0;

while((len=fread(data,1,1024,fp))>0){

socket().sendBytes(data, len);
i++;
printf("i=%d len=%d\n",i,len);

}
socket().close();



//}


}else{
// delete this;
return;
}
}
void run()
{
Application& app = Application::instance();
app.logger().information("Request from " + this->socket().peerAddress().toString());
try
{
/* Timestamp now;
std::string dt(DateTimeFormatter::format(now, _format));
dt.append("\r\n");
socket().sendBytes(dt.data(), (int) dt.length()); */

 int n = 0;
 char buf[10240];
//char buf[]="";



while(1){
 
  n = socket().receiveBytes(buf, 10240 );
struct PInfo* pi = (struct PInfo*)(buf);
 //std::cout << pi->filelength << pi->readystatus << std::endl;
 //获取列表;
//const char* str ="{\"uploadid\":\"1234\",\"code\":100,\"msg\":\"this is the json test\",\"files\":\"xxx.zip\"}";
if(pi->type==0){
sendList();
}else {
sendFile(n,buf);
}
  //sendFile(n,buf);


 

}

}catch (Poco::Exception& exc)
{
app.logger().log(exc);
}
}

private:
std::string _format;
};

class TimeServerConnectionFactory: public TCPServerConnectionFactory
/// A factory for TimeServerConnection.
{
public:
TimeServerConnectionFactory(const std::string& format):
_format(format)
{
}

TCPServerConnection* createConnection(const StreamSocket& socket)
{
return new TimeServerConnection(socket, _format);
}


private:
std::string _format;
};

class TimeServer: public Poco::Util::ServerApplication
 
{
public:
TimeServer(): _helpRequested(false)
{
}

~TimeServer()
{
}

protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
}

void uninitialize()
{
ServerApplication::uninitialize();
}

void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);

options.addOption(
Option("help", "h", "display help information on command line arguments")
.required(false)
.repeatable(false));
}


void handleOption(const std::string& name, const std::string& value)
{
ServerApplication::handleOption(name, value);


if (name == "help")
_helpRequested = true;
}

void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("A server application that serves the current date and time.");
helpFormatter.format(std::cout);
}

int main(const std::vector<std::string>& args)
{
if (_helpRequested)
{
displayHelp();
}
else
{
// get parameters from configuration file
unsigned short port = (unsigned short) config().getInt("TimeServer.port", 9911);
std::string format(config().getString("TimeServer.format", DateTimeFormat::ISO8601_FORMAT));

// set-up a server socket
ServerSocket svs(port);
// set-up a TCPServer instance
TCPServer srv(new TimeServerConnectionFactory(format), svs);
// start the TCPServer
srv.start();
// wait for CTRL-C or kill
waitForTerminationRequest();
// Stop the TCPServer
srv.stop();
}
return Application::EXIT_OK;
}

private:
bool _helpRequested;
};
int main(int argc, char** argv)
{
//写入注册表,开机自启动 
HKEY hKey; 
//找到系统的启动项 
//注意把项目支持的字符集改成支持多字符集
//选中解决方案管理器中的项目,右键->属性->配置属性->常规,在右面字符集一栏单击一下字符集编辑输入区域,在下拉框中选择“使用多字节字符集”即可 
LPCTSTR lpRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; 
//打开启动项Key 
long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey); 
if(lRet == ERROR_SUCCESS) 

char pFileName[MAX_PATH] = {0}; 
//得到程序自身的全路径 
//DWORD dwRet = GetModuleFileName(NULL,  pFileName, MAX_PATH); 
DWORD dwRet = GetModuleFileNameA(NULL,  pFileName, MAX_PATH); 
//添加一个子Key,并设置值
// 下面的"getip"是应用程序名字(不加后缀.exe)
lRet = RegSetValueEx(hKey,  "tcpserverpoco", 0, REG_SZ, (BYTE *)pFileName, dwRet);


//关闭注册表 
RegCloseKey(hKey); 
if(lRet != ERROR_SUCCESS) 

//AfxMessageBox("系统参数错误,不能随系统启动"); 
system("pause");

}
TimeServer app;
return app.run(argc, argv);
}


void getFiles(string path,vector<string>& files){
long hFile = 0;
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo))!=-1){

do  
{  
//如果是目录,迭代之  
//如果不是,加入列表  
if((fileinfo.attrib &  _A_SUBDIR))  
{  
if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)  
getFiles( p.assign(path).append("\\").append(fileinfo.name), files );  
}  
else  
{  
//files.push_back(p.assign(path).append("\\").append(fileinfo.name) );  
files.push_back(fileinfo.name);  
}  
}while(_findnext(hFile, &fileinfo)  == 0);  
_findclose(hFile); 
}
}




这篇关于poco库应用框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964853

相关文章

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述。以下是从不同角度对气象站的种类和应用范围的介绍: 一、气象站的种类 根据用途和安装环境分类: 农业气象站:专为农业生产服务,监测土壤温度、湿度等参数,为农业生产提供科学依据。交通气象站:用于公路、铁路、机场等交通场所的气象监测,提供实时气象数据以支持交通运营和调度。林业气象站:监测林区风速、湿度、温度等气象要素,为林区保护和

PyTorch模型_trace实战:深入理解与应用

pytorch使用trace模型 1、使用trace生成torchscript模型2、使用trace的模型预测 1、使用trace生成torchscript模型 def save_trace(model, input, save_path):traced_script_model = torch.jit.trace(model, input)<

哺乳细胞重组表达人鼠嵌合抗体:制备与应用

重组抗体是一类具有广泛应用价值的蛋白质,在药物研发和生物医学研究中发挥着重要作用。本文将介绍重组抗体的表达方式,重点关注嵌合抗体制备和哺乳细胞重组表达人鼠嵌合抗体的技术原理和应用。 重组抗体表达的原理和方法 重组抗体表达是通过将人或动物源的免疫球蛋白基因导入表达宿主细胞,并使其表达出特异性抗体蛋白质。常用的表达系统包括细菌、哺乳细胞和真核微生物等。 嵌合抗体制备的步骤和优势 选择适当的抗原

[分布式网络通讯框架]----Zookeeper客户端基本操作----ls、get、create、set、delete

Zookeeper数据结构 zk客户端常用命令 进入客户端 在bin目录下输入./zkCli.sh 查看根目录下数据ls / 注意:要查看哪一个节点,必须把路径写全 查看节点数据信息 get /第一行代码数据,没有的话表示没有数据 创建节点create /sl 20 /sl为节点的路径,20为节点的数据 注意,不能跨越创建,也就是说,创建sl2的时候,必须确保sl

【服务器08】之【游戏框架】之【加载主角】

首先简单了解一下帧率 FixedUpdate( )   >   Update( )   >   LateUpdate( ) 首先FixedUpdate的设置值 默认一秒运行50次 虽然默认是0.02秒,但FiexedUpdate并不是真的0.02秒调用一次,因为在脚本的生命周期内,FixedUpdate有一个小循环,这个循环也是通过物理时间累计看是不是大于0.02了,然后调用一次。有

Java中的集合框架使用技巧

Java中的集合框架使用技巧 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨Java中集合框架的使用技巧,这些技巧能够帮助我们更高效地处理数据和优化程序性能。 Java集合框架概述 Java集合框架提供了一组实现了各种集合接口的类和接口,用于存储和操作数据。它包括列表、集合、队列和映射等数据结构,能够满足不

【Qt6.3 基础教程 16】 掌握Qt中的时间和日期:QTimer和QDateTime的高效应用

文章目录 前言QTimer:定时任务的强大工具QTimer的基本用法高级特性:单次定时器 QDateTime:处理日期和时间获取当前日期和时间日期和时间的格式化输出日期和时间计算 用例:创建一个倒计时应用结论 前言 在开发桌面应用程序时,处理时间和日期是一个常见且重要的任务。Qt框架提供了强大的工具来处理与时间相关的功能,其中QTimer和QDateTime是最核心的类。本