Qt之显示PDF文件

之前使用过mupdf库,能够成功显示pdf,但是我用着有BUG,不太理解它的代码,搞了好久都不行。后面又试了其他库,如pdfium、popler、下载了很多例程,都跑不起来!后面偶然得知xpdf库,看起来应该容易编译,因此这里主要是针对xpdf库的编译。

目前状态:终于成功了!2023-10-06(直接看章节3即可)

20231006_222307

一、官网

Download Xpdf and XpdfReader

官网有大致的介绍,以及最新版本的xpdf源码的下载链接。但是没有具体讲怎么移植xpdf。

二、windows下的xpdf的编译

2.1、准备windows下的编译环境

我的编译环境

win10操作系统

vs2015社区版

qt版本:qt5.9.5

在官网下载工具链。如下图红色框中所示,点击后即可下载。这个压缩包是linux下的格式,解压需要费点功夫。

下载并解压后放在xpdf源码目录下,如下图所示。

2.2、编译freetype

在如下图的路径,双击使用VS打开freetype.sln(我的VS是vs2015社区版),选择Release和win32后,点击运行进行编译,编程出dll文件。(由于dll不能直接运行,因此会报如下的错误,忽略即可)。

编译完成在 如下的路径下即可看到dll和lib文件。

工程路径:\freetype-2.12.0\builds\windows\vc2010

编译结构路径:\freetype-2.12.0\objs

在xpdf源码目录新建文件夹freetype,将刚才生成的lib和dll文件拷贝到该文件夹中,就完成了freetype的编译。

2.3、编译lcms

在如下图路径打开lcms的工程,右键点击lcms2_DLL将其设为启动项目,选择Release和win32后,点击运行进行编译,编程出dll文件。

工程路径:\lcms2-2.12\Projects\VC2015

编译结构路径:\lcms2-2.12\bin

在xpdf源码目录新建文件夹lcms,将刚才生成的lib和dll文件拷贝到该文件夹中,就完成了lcms的编译。

2.4、编译zlib

zlib-1.2.12版本有点bug,需要先处理一下。

1、拷贝zlib-1.2.11(去网上下载一个)中的masmx76到contrib目录下;

2、修改代码

 (1)修改函数uLong ZEXPORT crc32_combine(crc1, crc2, len2)
    z_off_t len2改为z_off64_t len2;

(2)修改函数:uLong ZEXPORT crc32_combine_gen(len2)
    z_off_t len2改为z_off64_t len2

(3)修改函数:uLong crc32_combine_op(crc1, crc2, op)

改为uLong ZEXPORT  crc32_combine_op(crc1, crc2, op)

3、右键zlibvc,设置 SAFESEH 映像是不安全的异常处理程序关闭

完成 后开始正式的编译。

在如下图路径打开zlib的工程,选择Release和win32后,点击运行进行编译,编程出dll文件。

工程路径:\zlib-1.2.12\contrib\vstudio\vc14

编译结构路径:\zlib-1.2.12\contrib\vstudio\vc14\x86\ZlibDllRelease

在xpdf源码目录新建文件夹zlib,将刚才生成的lib和dll文件拷贝到该文件夹中,就完成了zlib的编译。

如果出现异常情况:

问题1.没有bld_ml32.bat

编译器报错详情:

问题解决:查看contrib目录下,确实没有masmx86,拷贝zlib-1.2.11中的masmx86和masmx64到contrib目录下,问题解决。

问题2.实参的字节长度不同于以前的调用或引用

编译器报错详情如下:

问题解决:在crc32.c中修改如下内容

1.修改函数uLong ZEXPORT crc32_combine(crc1, crc2, len2)
    uLong crc1;
    uLong crc2;
    z_off_t len2;为z_off64_t len2;

2.修改函数:1.uLong ZEXPORT crc32_combine_gen(len2)
    z_off_t len2;为z_off64_t len2

3.修改:

uLong crc32_combine_op(crc1, crc2, op)为

uLong ZEXPORT  crc32_combine_op(crc1, crc2, op)

问题3:模块对于 SAFESEH 映像是不安全的。

使用Release编译,忽略其他编译警告,编译通过。
 

2.5、编译libpng

libpng的编译以来zlib,因此需要将zlib的源码放在libpng源码的同级目录(前面已经放过了)

打开zlib.props文件,修改zlib的路径和版本(放在同级目录就不需要修改路径,修改版本就行)

在如下图路径打开libpng的工程,右键点击libpng将其设为启动项目,选择Release和win32后,点击运行进行编译,编程出dll文件。

工程路径:\libpng-1.6.35\projects\vstudio

编译结构路径:\libpng-1.6.35\projects\vstudio\Release

在xpdf源码目录新建文件夹libpng,将刚才生成的lib和dll文件拷贝到该文件夹中,就完成了libpng的编译。

2.6、编译xpdf

2.6.1 设置编译参数

(1) 在xpdf源码目录下新建bulid文件夹,

(2) 打开vs2015的命令提示符工具(看你的vs版本),并进入build路径(ctrl+c后在命令框右键即可粘贴)

输入如下命令,设置各个库的包含路径和动态库的路径

cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DFREETYPE_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/freetype/freetype.dll" -DFREETYPE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/freetype-2.12.0" -DPNG_PNG_INCLUDE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/libpng-1.6.35" -DPNG_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/libpng/libpng16.dll" -DZLIB_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/zlib/zlibwapi.dll" -DZLIB_INCLUDE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/zlib" ..

我的结果如下:

E:\qt5.9.5\userfile\20231005\xpdf-4.04\build>cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DFREETYPE_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/freetype/freetype.dll" -DFREETYPE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/freetype-2.12.0" -DPNG_PNG_INCLUDE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/libpng-1.6.35" -DPNG_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/libpng/libpng16.dll" -DZLIB_LIBRARY="E:/qt5.9.5/userfile/20231005/xpdf-4.04/zlib/zlibwapi.dll" -DZLIB_INCLUDE_DIR="E:/qt5.9.5/userfile/20231005/xpdf-4.04/zlib" ..
-- The C compiler identification is MSVC 19.0.24215.1
-- The CXX compiler identification is MSVC 19.0.24215.1
-- Check for working C compiler: F:/vs2015/VC/bin/cl.exe
-- Check for working C compiler: F:/vs2015/VC/bin/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: F:/vs2015/VC/bin/cl.exe
-- Check for working CXX compiler: F:/vs2015/VC/bin/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for mkstemp
-- Looking for mkstemp - not found
-- Looking for mkstemps
-- Looking for mkstemps - not found
-- Looking for popen
-- Looking for popen - not found
-- Performing Test HAVE_STD_SORT
-- Performing Test HAVE_STD_SORT - Success
-- Looking for fseeko
-- Looking for fseeko - not found
-- Looking for fseek64
-- Looking for fseek64 - not found
-- Looking for _fseeki64
-- Looking for _fseeki64 - found
-- Found FreeType (old-style includes): E:/qt5.9.5/userfile/20231005/xpdf-4.04/freetype/freetype.dll
-- Found ZLIB: E:/qt5.9.5/userfile/20231005/xpdf-4.04/zlib/zlibwapi.dll
-- Found PNG: E:/qt5.9.5/userfile/20231005/xpdf-4.04/libpng/libpng16.dll (found version "1.6.35")
-- Qt5 found
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: E:/qt5.9.5/userfile/20231005/xpdf-4.04/build

2.6.2 开始编译

在命令框输入:

nmake

我失败在如下这一步(2023-10-05)

三、xpdf库在windows上新建QT工程

如需源码,请上闲鱼,搜索:科技代码小卖部

3.1 新建一个新工程

在qtcreator下新建工程,如下图XPDFDemo20231006New4_04

3.2 拷贝头文件

(1)拷贝freetype库的头文件到新工程目录下

在freetype库的源码下,拷贝整个include文件夹到新工程目录。

(2)拷贝freetype库的库文件(lib和dll)到新工程目录下

在新工程目录下新建lib文件夹,拷贝编译后的freetype库文件到该路径下(编译方法见前面的2.2小节)

(3)拷贝xpdf的头文件到新工程目录下

将xpdf库源码中的相关头文件拷贝到新工程目录下,新建一个aconf.h文件,将下面的代码拷贝到里面(源码里只有aconf.h.in,需要编译才能生成aconf.h,如想自行编译,见2.6小节,在build文件夹下编译后会生成aconf.h文件)

/** aconf.h** This file is modified by cmake.** Copyright 2002-2015 Glyph & Cog, LLC*/#ifndef ACONF_H
#define ACONF_H#include <aconf2.h>/** Use A4 paper size instead of Letter for PostScript output.*/
#define A4_PAPER 1/** Do not allow text selection.*/
#define NO_TEXT_SELECT 0/** Include support for OPI comments.*/
#define OPI_SUPPORT 1/** Enable multithreading support.*/
#define MULTITHREADED 0/** Enable C++ exceptions.*/
#define USE_EXCEPTIONS 1/** Use fixed point (instead of floating point) arithmetic.*/
#define USE_FIXEDPOINT 1/** Enable support for CMYK output.*/
#define SPLASH_CMYK 1/** Enable support for DeviceN output.*/
#define SPLASH_DEVICEN 1/** Enable support for highlighted regions.*/
#define HIGHLIGHTED_REGIONS 1/** Full path for the system-wide xpdfrc file.*/
//@SYSTEM_XPDFRC_DEFINE@/** Directory to use for the ${DATADIR} variable in the xpdfrc config* file.*/
//@XPDFRC_DATADIR_DEFINE@/** Various include files and functions.*/
#define HAVE_MKSTEMP 1
#define HAVE_MKSTEMPS 1
#define HAVE_POPEN 1
#define HAVE_STD_SORT 1
#define HAVE_FSEEKO 0
#define HAVE_FSEEK64 0
#define HAVE_FSEEKI64 1
#define _FILE_OFFSET_BITS 64
#define _LARGE_FILES 1
#define _LARGEFILE_SOURCE 1/** This is defined if using FreeType 2.*/
#define HAVE_FREETYPE_H 1/** This is defined if using D-Type 4.*/
#define HAVE_DTYPE4_H 0/** This is defined if using libpaper.*/
#define HAVE_PAPER_H 0/** This is defined if using libfontconfig.*/
#define HAVE_FONTCONFIG 0/** Defined if the Splash library is avaiable.*/
#define HAVE_SPLASH 0/** Defined if using lcms2.*/
#define HAVE_LCMS 0/** Defined for evaluation mode.*/
#define EVAL_MODE 1/** Defined when building the closed source XpdfReader binary.*/
#define BUILDING_XPDFREADER 0#endif

(4)拷贝xpdf例程到新工程中

将xpdf库源码中的xpdf-qt文件夹拷贝到新工程目录下。

3.3 配置pro文件

删除core和gui模块,添加QT库network,printsupport和axcontainer。如下图所示     

  添加头文件和库文件的检索路径

3.4 添加已有文件到新工程

在Header上右键,选择Add Existing Directory,勾选所有需要导入的文件,批量完成导入。

在默认的基础上,把2个rc资源文件也勾选上,如下图所示。

3.5 删除多余文件

由于例程没有用qt界面编辑器,且自带main函数,因此需要将原新建工程的以下文件删除:

main.cpp

mainwindow.h

mainwindow.cpp

mainwindow.ui

删除后的工程结构如下图所示。

3.6 修改源码

源码还有点错误,需要修改。先点击运行进行编译,会报如下的错误。

(1)修改XpdfViewer.cc

打开XpdfViewer.cc文件,添加头文件

#include <time.h>

(2)修改XpdfApp.cc

由于字符集的问题,需要将XpdfApp.cc中的void XpdfApp::readPagesFile() 函数整个换为下方的代码,进行字符转换。

char * wchar2char(const wchar_t* szUnicodeString)
{UINT nCodePage = 936; //GB2312int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);char* pBuffer=new char[nLength+1];WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);pBuffer[nLength]=0;return pBuffer;}wchar_t * char2wchar(const char* cchar)
{wchar_t *m_wchar;int len = MultiByteToWideChar( CP_ACP ,0,cchar ,strlen( cchar), NULL,0);m_wchar= new wchar_t[len+1];MultiByteToWideChar( CP_ACP ,0,cchar,strlen( cchar),m_wchar,len);m_wchar[len]= '\0' ;return m_wchar;
}void XpdfApp::readPagesFile() {// construct the file name (first time only)if (savedPagesFileName.isEmpty()) {
#ifdef _WIN32        wchar_t wpath[MAX_PATH];//    char path[MAX_PATH];if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL,SHGFP_TYPE_CURRENT, wpath) != S_OK) {return;}//char path[MAX_PATH];char* path=wchar2char(wpath);savedPagesFileName = QString::fromLocal8Bit(path);savedPagesFileName.append("/xpdf");CreateDirectory(char2wchar(savedPagesFileName.toLocal8Bit().constData()), NULL);savedPagesFileName.append("/xpdf.pages");//        char path[MAX_PATH];
//        if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL,
//                            SHGFP_TYPE_CURRENT, path) != S_OK) {
//            return;
//        }
//        savedPagesFileName = QString::fromLocal8Bit(path);
//        savedPagesFileName.append("/xpdf");
//        CreateDirectory(savedPagesFileName.toLocal8Bit().constData(), NULL);
//        savedPagesFileName.append("/xpdf.pages");
#elseGString *path = getHomeDir();savedPagesFileName = QString::fromUtf8(path->getCString());delete path;savedPagesFileName.append("/.xpdf.pages");
#endif}// no change since last read, so no need to re-readif (savedPagesFileTimestamp.isValid() &&QFileInfo(savedPagesFileName).lastModified() == savedPagesFileTimestamp) {return;}// mark all entries invalidfor (int i = 0; i < maxSavedPageNumbers; ++i) {savedPageNumbers[i].fileName.clear();savedPageNumbers[i].pageNumber = 1;}// read the fileFILE *f = openFile(savedPagesFileName.toUtf8().constData(), "rb");if (!f) {return;}char buf[1024];if (!fgets(buf, sizeof(buf), f) ||strcmp(buf, "xpdf.pages-1\n") != 0) {fclose(f);return;}int i = 0;while (i < maxSavedPageNumbers && fgets(buf, sizeof(buf), f)) {int n = (int)strlen(buf);if (n > 0 && buf[n-1] == '\n') {buf[n-1] = '\0';}char *p = buf;while (*p != ' ' && *p) {++p;}if (!*p) {continue;}*p++ = '\0';savedPageNumbers[i].pageNumber = atoi(buf);savedPageNumbers[i].fileName = QString::fromUtf8(p);++i;}fclose(f);// save the timestampsavedPagesFileTimestamp = QFileInfo(savedPagesFileName).lastModified();
}

(3)完成后又会报如下图的错误

png.h是libpng库里的头文件,如果不需要pdf转html,转txt等功能,将把对应的.cc文件删掉。如果需要,就要编译libpng库,并导入对应的头文件。(我这里不需要这些高级的功能,就直接删掉了),需要删掉的文件如下:

HTMLGen.cc

pdftopng.cc

删除后重新执行qmake命令,然后点击运行。

(4)完成后又会报如下图的错误

 这是因为前面说的的高级功能,每个都有main函数并能生成各自的exe文件,从而导致main函数重复了。把他们都删除掉,需要删除的文件如下:

pdfdetach.cc

pdffonts.cc

pdfimages.cc

pdfinfo.cc

pdftohtml.cc

pdftoppm.cc

pdftops.cc

pdftotext.cc

同样,完成后重新执行qmake命令,然后点击运行。

3.6 xpdf库的使用

前面设置好,xpdf库的配置就已经完成了,已经可以开始使用了。点击运行即弹出程序。(ENJOY!!!!!)

四、xpdf库的自用

如需源码,请上闲鱼,搜索:科技代码小卖部

4.1 打开pdf文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++-封装unordered

本期我们来封装实现unordered系列&#xff0c;需要前置知识&#xff0c;没有看过哈希的建议先看看哈希&#xff0c;而且哈希的代码都在这里面&#xff0c;一会要用到 C-哈希Hash-CSDN博客 目录 代码实现 迭代器 const迭代器 全部代码 代码实现 首先我们要把V改为T&#xff…

2023-10-06 LeetCode每日一题(买卖股票的最佳时机含手续费)

2023-10-06每日一题 一、题目编号 714. 买卖股票的最佳时机含手续费二、题目链接 点击跳转到题目位置 三、题目描述 给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续费用。 你可以无限次地完成交易&…

STM32复习笔记(一):软件配置工程创建

目录 Preface&#xff1a; Hardware-Configuration & Software-Environment&#xff1a; &#xff08;一&#xff09;新建项目工程 &#xff08;二&#xff09;工程配置 &#xff08;三&#xff09;配置外设 &#xff08;四&#xff09;项目管理 &#xff08;五&…

区别对比表:阿里云轻量服务器和云服务器ECS对照表

阿里云轻量应用服务器和云服务器ECS区别对照表&#xff0c;一看就懂的适用人群、使用场景、优缺点、使用限制、计费方式、网路和镜像系统全方位对比&#xff0c;阿里云服务器网分享ECS和轻量应用服务器区别对照表&#xff1a; 目录 轻量应用服务器和云服务器ECS区别对照表 轻…

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真+程序+原理图+报告+讲解视频)

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真程序原理图报告讲解视频&#xff09; 讲解视频1.主要功能&#xff1a;2.仿真3. 程序代码4.原理图5. 设计报告6. 设计资料内容清单 51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显…

MySQL视图、用户管理

目录 视图概念和操作 视图基本操作 视图规则和限制 用户管理 用户 视图概念和操作 什么是视图&#xff1f; 视图是一个虚拟表&#xff0c;由一个或多个基本表的查询结果组成&#xff08;视图是存储在数据库中的查询的SQL 语句&#xff0c;不在数据库中以存储的数据值集形式…

Verilator: sh: 1: exec: < PATHNAME >: not found

事出有因 I assumed that I install verilator via git clone its source, so I need to set the export VERILATOR_ROOT. At first, due to laziness, I just copy the code directly to my ubuntu. so stupid I am!!! Then, I recoginzed that the pathname is not real, …

wireshark of tshark tools v3.4.0版本 支持json

tshark(1) Install tshark (Wireshark) Ver.3.4.0 on CentOS7 --It must be "ps", "text", "pdml", "psml" or "fields". TCP 协议中的三次握手和四次挥手是 TCP 连接建立和关闭的过程。 三次握手 客户端向服务器发送 SYN…

JMeter学习第一、二、三天

首先&#xff0c;我们来了解一下到底什么是接口测试与性能测试&#xff1a; 接口测试 定义 接口测试主要关注系统组件之间的交互&#xff0c;确保各个接口按预期工作。这包括验证传递的数据、数据格式、调用的频率和其他与接口调用相关的任何限制。 目的 确保系统的各个组件可…

mac清理垃圾的软件有哪些?这三款我最推荐

没错&#xff0c;Mac电脑真的好用&#xff0c;但是清理系统垃圾可不是件容易的事。由于Mac系统的封闭性&#xff0c;系统的缓存垃圾常常隐藏得让人发现不了。不过&#xff0c;别担心&#xff01;有一些专业的Mac清理软件可以帮你解决这一系列问题&#xff0c;让清理垃圾变得轻松…

10链表-单链表构造LinkedList

目录 LeetCode之路——707. 设计链表 分析&#xff1a; Code&#xff1a; LeetCode之路——707. 设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;n…

什么是TF-A项目的长期支持?

安全之安全(security)博客目录导读 问题&#xff1a;Trusted Firmware-A社区每六个月发布一次代码。然而&#xff0c;对于生产中的平台&#xff0c;该策略在维护、重要软件修复的向后兼容性、获得最新的安全缓解措施和整体产品生命周期管理方面不具备可扩展性。 开源软件项目&…

【C++设计模式之原型模式:创建型】分析及示例

简介 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许通过复制已有对象来生成新的对象&#xff0c;而无需再次使用构造函数。 描述 原型模式通过复制现有对象来创建新的对象&#xff0c;而无需显式地调用构造函数或暴露对象的创建…

LDGRB-01 用于在边缘处理人工智能的嵌入式硬件

LDGRB-01 用于在边缘处理人工智能的嵌入式硬件商业和企业中的IT系统正在全面快速发展&#xff0c;一个不断增长的趋势正在将计算能力推向边缘。Gartner预测&#xff0c;到2025年&#xff0c;边缘计算将处理75%的数据由所有用例产生&#xff0c;包括工厂、医疗保健和运输中的用…

[GXYCTF2019]禁止套娃 无回显 RCE 过滤__FILE__ dirname等

扫除git 通过githack 获取index.php <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br>"; if(isset($_GET[exp])){if (!preg_match(/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i, $_GET[exp])) {if(; preg_replace(/[a-z,_]\(…

Vue中如何进行响应式图像与图片懒加载优化

Vue中响应式图像与图片懒加载优化 在现代的Web开发中&#xff0c;图像在网站性能和用户体验方面扮演着至关重要的角色。然而&#xff0c;加载大量的图像可能会导致网页加载速度变慢&#xff0c;从而影响用户的满意度。为了解决这个问题&#xff0c;Vue.js提供了一些强大的工具…

【gitlab】git push -u origin master 报403

问题描述 gitlab版本&#xff1a;14.0.5 虚拟机版本&#xff1a;centos7 项目&#xff1a;renren-fast 原因分析 .git -> config目录下 url配错 但这个url不是手动配置的&#xff0c;还不知道怎么生成。 解决方法 把配置错误的url改成gitlab的project的url 这样&#…

Android学习之路(20) 进程间通信

IPC IPC为 (Inter-Process Communication) 缩写&#xff0c;称为进程间通信或跨进程通信&#xff0c;指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信&#xff0c;当然也支持其他 IPC 方式&#xff0c;如&#xff1a;管道&#xff0c;Socket&#xff0…

VS Code更改软件的语言

刚刚安装好的 vscode 默认是英文&#xff0c;可以安装中文扩展包。如图&#xff1a; 重启即可更换为中文。 如果想切换为英文&#xff0c;可以 Ctrl Shift P&#xff0c;打开命令面板。 输入 Configure DIsplay Language&#xff0c;如图&#xff1a; 可以在中英文之间切换…

10.04

QT实现TCP服务器客户端搭建的代码&#xff0c;现象 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpSocket> #include <QMessageBox>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : p…