草上爬
专注技术,热爱分享
展开
-
Qt基础之四十六:Qt界面中嵌入第三方程序的一点心得
本文主要讲解QWidget和QWindow的区别,以及如何在QWidget中嵌入第三方程序,并完美解决在QWidget中嵌入某些程序(比如Qt程序)时出现的白边问题。原创 2024-04-21 18:54:25 · 4942 阅读 · 14 评论 -
Qt基础之四十五:Qt国际化(I18N)
国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),这种奇葩的缩写方式,让我想起了NBA球星“字母哥”。下面看下Qt实现的动态语言切换效果。原创 2023-12-31 20:56:04 · 3950 阅读 · 13 评论 -
Qt基础之四十四:qmake构建原理
qmake构建原理。当一个项目很小的时候,直接使用编译器、链接器等编译工具,就可以把代码构建成程序。当项目越来越大时,除了需要调用编译工具编译程序,还需要做很多事情,例如:☆配置编译工具☆设置编译选项☆添加头文件☆添加第三方库☆添加资源文件☆自动增量编译,自动检测文件修改☆链接程序☆软件自动部署☆自动化测试等等完成这些步骤,需要调用几个甚至几十个工具来完成。这导致构建软件的任务变得非常繁琐,如果每次构建都需要开发者手动逐个调用工具完成,就会产生大量的、机械的重复性劳动。原创 2018-04-04 16:58:24 · 10454 阅读 · 1 评论 -
Qt基础之四十三:Qt智能指针(QPointer、QSharedPointer、QWeakPointer和QScopedPointer)
Qt智能指针(QPointer、QSharedPointer、QWeakPointer和QScopedPointer)原创 2023-12-30 00:10:13 · 3674 阅读 · 1 评论 -
Qt基础之四十二:QMap、QHash的实现原理和性能对比
QMap、QHash的实现原理和性能对比:红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树为了保证其最长路径中节点个数不会超过最短路径节点个数的两倍,具有以下五个特性:(1)每个结点不是红色就是黑色(2)根节点是黑色的(3)如果一个节点是红色的,则它的两个孩子结点是黑色的。原创 2023-12-15 18:56:50 · 5101 阅读 · 0 评论 -
Qt基础之四十一:记一次QVector的bad alloc问题追踪
记一次QVector的bad alloc问题追踪原创 2023-12-07 23:50:03 · 5261 阅读 · 1 评论 -
Qt基础之四十:Qt Installer Framework(QtIFW)的编译、使用和实现原理
Qt Installer Framework(QtIFW)的编译、使用和实现原理原创 2023-12-02 15:01:06 · 6028 阅读 · 1 评论 -
Qt基础之三十九:Qt Creator调试技巧
Qt Creator调试技巧一.开始调试(F5)二.调试dll1.Attach to Running Application2.Attach to Running Application3.Start and Debug External Application三.调试源码1.MinGW2.MSVC原创 2023-10-27 19:07:09 · 6142 阅读 · 0 评论 -
Qt基础之三十八:快捷键
一.按钮的快捷键二.菜单项的快捷键1.菜单栏菜单2.快捷菜单三.QShortcut四.快捷键冲突的处理五.全局快捷键原创 2023-10-22 23:02:00 · 4938 阅读 · 0 评论 -
Qt基础之三十七:是否发生复制?浅谈参数在信号-槽中的传递
当信号的参数是对象的常引用,且槽的参数也是对象的常引用,那么这个对象会复制多少次呢?信号和槽的direct和queued连接方式有何不同?如果信号和槽的参数都按值传递,会发生什么变化呢?这个问题通常会在项目的某个时刻(比如说性能优化时)提及,但Qt文档对此只字未提。关于有一个很好的讨论,不过需要读者从所有评论中选择正确的答案。因此,下面让我们系统地讨论参数是如何在信号和槽间传递的。翻译 2023-10-03 15:58:33 · 4948 阅读 · 0 评论 -
Qt基础之三十六:异常处理
本文将介绍如何在Qt中使用try...catch和调试dump文件来处理异常。Qt版本5.12.6。原创 2023-05-28 10:39:09 · 10397 阅读 · 0 评论 -
Qt基础之三十五:Qt中文乱码探索
Qt中文乱码看这一篇就够了先说个小技巧:Qt Creator支持显示源文件编码格式右上角点UTF-8,会弹出“文件编码”对话框我的开发环境是Win10 Qt5.12.6 VS2017,IDE是Qt Creator。原创 2023-04-07 00:13:12 · 6411 阅读 · 1 评论 -
Qt基础之三十四:QTcpSocket和QTcpServer源码分析
QTcpSocket和QTcpServer源码分析原创 2023-04-03 23:47:20 · 5714 阅读 · 0 评论 -
Qt基础之三十三:海量网络数据实时显示
开发中我们可能会遇到接收的网络数据来不及显示的问题。最基础的做法是限制UI中加载的数据行数,这样一来可以防止内存一直涨,二来数据刷新非常快,加载再多也来不及看。此时UI能看到数据当前处理到什么阶段就行,实时性更加重要,要做数据分析的话还得查看日志文件。这里给出UDP+QListView和TCP+QPlainTexEdit两种实现方案。原创 2023-03-19 11:34:11 · 7450 阅读 · 2 评论 -
Qt基础之三十二:浅谈qDebug()
我们先来看看qDebug()的基本用法,再去研究qDebug的实现原理。除了qDebug(),Qt还提供了qInfo()、qWarning()、qCritical()方便我们打印不同种类的信息,而qFatal()直接结束程序,后面代码不再执行,用的较少。在Unix/X11和macOS,调试信息会打印到stderr;在Windows,如果是控制台程序,调试信息会输出到控制台,否则会输出到调试器(debugger)—比如说Qt Creator的应用程序输出(Application Output)窗口。原创 2023-03-18 09:56:48 · 7610 阅读 · 0 评论 -
Qt基础之三十一:Qt网络编程(TCP&UDP)
Qt网络模块(Network)提供了编写TCP/IP客户端和服务器的类。该模块不仅提供了低级(low-level)类,如QTcpSocket、QTcpServer和QUdpSocket,还提供了高级(hight-level)类,如QNetworkRequest、QNetworkReply和QNetworkAccessManager。原创 2023-03-14 22:21:04 · 6207 阅读 · 0 评论 -
Qt基础之三十:百万级任务并发处理
体现线程快的核心是延迟和吞吐量,延迟就是每个发送请求到收到响应所消耗的时间,延迟越短,程序越快,性能也越好。对于CPU密集型计算多线程本质上是提升CPU的使用率,所以对一个4核的CPU来说,理论上创建4个线程就可以了。我们都知道在进行I/O操作时,CPU是空闲状态,所以我们要最大化的利用CPU,不能让其是空闲状态。如图所示:CPU 在 A、B、C 三个线程之间切换,对于线程 A,当 CPU 从 B、C 切换回来时,线程 A 正好执行完 I/O 操作。CPU和I/O的耗时如果是1:1那开2个线程是合适的。原创 2023-02-28 23:03:17 · 5792 阅读 · 1 评论 -
Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用
无意中从网络获取一份俄罗斯方块源码,基于图形视图框架(Graphics View Framework)实现的。当然源码的核心从来都不是界面,而是方块的移动、变形和消除等算法。源码非常完整,注释详细,经改动后已能在Qt5中运行,下面是运行效果,背景音乐和音效也是有的。原创 2023-02-21 22:45:40 · 6227 阅读 · 1 评论 -
Qt基础之二十八:在Qt中使用单例模式的最佳实践
ARGS被用来传入Type构造函数所需的参数,Q_GLOBAL_STATIC的ARGS是空括号(),表示调用Type的无参构造函数,如果我们使用Q_GLOBAL_STATIC_WITH_ARGS给它参数,就是调用对应的带参构造函数了。Q_GLOBAL_STATIC宏定义的变量则消除了这些问题,Q_GLOBAL_STATIC仅在第一次调用时才构造和初始化,节省了应用程序初始化加载的时间,确保了是线程安全的。使用Q_GLOBAL_STATIC_INTERNAL宏定义了一个innerFunction函数。原创 2016-05-14 17:58:55 · 11647 阅读 · 1 评论 -
Qt基础之二十七:访问SQLite数据库
Qt通过不同的数据库驱动来实现访问不同的数据库,QSqlDriver是一个抽象类,是所有数据库驱动类的基类。Qt支持访问很多不同的数据库,例如Sqlite,MySQL,SqlServer等,但是Qt具体都支持哪些数据库呢?在QtAssistant中输入QSqlDatabase,可以看到Qt目前支持的所有数据库。.........原创 2017-12-19 17:33:40 · 8241 阅读 · 1 评论 -
Qt基础之二十六:Qt绘图系统(Paint System)
通过从QPaintDevice类派生并重新实现QPaintDevice:paintEngine()函数,即可添加一个新的绘图设备。在paintEngine中要告知QPainter应该使用哪种绘图引擎在该设备上绘制。要真正能够在自定义绘图设备上绘制,此绘图引擎必须是从QPaintEngine类派生的自定义绘图引擎。原创 2023-02-11 23:15:13 · 6370 阅读 · 0 评论 -
Qt基础之二十五:动画框架(Animation Framework)
Qt动画框架的设计目的是提供一种简单的方法用于创建动态和平滑的GUI。通过作用于Qt属性,Qt动画框架为窗口部件和其他QObject对象的动画操作提供了非常大的自由。Qt动画框架也能用于图形/视图(Graphics View)框架中。在本文中,我将阐述了Qt动画框架的基本结构,并提供例子来演示该框架如何运用相关技术实现QObjects和graphics items的动画效果。原创 2017-01-01 10:04:34 · 13189 阅读 · 1 评论 -
Qt基础之二十四:深入理解插件系统
Qt提供了两类API来创建插件:☆high-level API用于创建Qt自身的扩展,比如说自定义数据库驱动、图像格式、文本编码、样式,等等☆low-level API用于扩展Qt应用程序如果你想为Qt Designer提供插件,可以参考Qt Assistant:Qt Designer Manual。原创 2018-11-11 17:13:21 · 8331 阅读 · 0 评论 -
Qt基础之二十三:反射(Reflection)
不同于boost这样的模板库,Qt利用自带的Meta-Object Compiler(moc)来生成额外的C++代码,这些代码实现了Qt程序所必须的元数据对象,可以说Qt是基于C++的一种扩展。反射是指程序在运行时动态获取对象属性与方法的一种机制,即编译器需要将类型信息(属性类型与偏移地址以及成员函数的地址等信息)编译到程序文件中,当程序运行时将这些信息加载到内存中去,做到运行时只根据对象的地址或引用就可以获取到对象的类型信息,从而利用这些信息达到修改或重建对象的目标。☆在运行时调用对象的方法;原创 2023-01-25 13:26:33 · 10290 阅读 · 0 评论 -
Qt基础之二十二:重启应用程序
重启应用程序有两个常见的引用场景,切换账号和保存特定配置后需要重启。有时候程序运行出现问题,也希望能够通过重启来解决。重启实际上就是关闭当前应用程序,然后再启动一个新的进程执行当前应用程序。原创 2016-05-14 15:37:25 · 6900 阅读 · 0 评论 -
Qt基础之二十一:QtRO(Qt Remote Object)实现进程间通信
这里将QtRO单独从上一篇拎出来,因为它是Qt5.9以后新加入的模块,专门用于进程间通信。其使用步骤有点类似之前介绍过的RPC(Remote Procedure Call)框架:gRPC和thrift,关于这两个框架详见和QtRO基于Socket封装,不仅支持RPC,还支持LPC(Local Process Communication),这两者都属于进程间通信。如果是用于RPC,使用QTcpSocket;如果用于LPC,则使用QLocalSocket。因为是Qt出品,能非常方便的集成到自己的Qt项目中。原创 2023-01-13 23:57:23 · 6417 阅读 · 2 评论 -
Qt基础之二十:进程间通信
进程间通信(IPC:Inter-Process Communication),就是在不同进程之间传播或交换信息。那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件。除此以外,那就是双方都可以访问的外设了。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息。原创 2023-01-08 14:59:03 · 7119 阅读 · 0 评论 -
Qt基础之十九:进程与QProcess
进程就是一个程序的执行实例,也就是正在运行的程序。对操作系统来说,进程就是一个担当分配系统资源CPU时间、内存的实体。在Qt 中,我们使用QProcess来表示一个进程。这个类可以允许我们的应用程序启动一个新的外部程序,并且与这个程序进行通讯。当外部程序开始启动时,QProcess的状态为Starting;外部程序已经启动时,QProcess的状态为Running,并发送started()信号;当外部层序退出了,QProcess的状态为NotRunning(初始状态),并发送finished()信号。原创 2016-04-16 13:52:22 · 14120 阅读 · 0 评论 -
Qt基础之十八:WebEngine与JavaScript交互
Qt从5.6开始就用Qt Webengine替换了Qt WebKit,据说加载速度较Qt WebKit更快。需在pro中添加QT += webenginewidgets。原创 2023-01-04 22:41:19 · 5930 阅读 · 0 评论 -
Qt基础之十七:WebKit与JavaScript交互
Qt从5.6开始不再支持QtWebKit,「QtWebKit got deprecated upstream in Qt 5.5 and removed in 5.6」。不过github上有人维护了一个版本,而且在持续更新中。如果想在高版本中使用QtWebKit,需要自行编译QtWebKit模块,编译步骤详见本文第二节。原创 2016-03-30 15:04:16 · 16866 阅读 · 2 评论 -
Qt基础之十六:QtConcurrent和QThreadPool
QtCurrent模块能处理一些常见的并行计算:map、filter和reduce。它们返回一个QFuture对象,该对象可用于获取函数执行的结果。QFuture还可用于查询计算进度和暂停/恢复/取消计算。为了方便起见,QFutureWatcher可以通过信号和插槽与QFuture进行交互。QtCurrent的map、filter和reduce算法自动将计算分布到所有可用的处理器核上,因此,当QtCurrent在多核系统上更有优势。原创 2023-01-02 09:48:23 · 5618 阅读 · 1 评论 -
Qt基础之十五:优雅地结束线程
如果一个线程运行完成,就会结束。可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它。不恰当的中止往往会引起一些未知错误。比如:当关闭主界面的时候,很有可能次线程正在运行,这时,就会出现如下提示:这个问题在使用线程的过程中经常遇到,尤其是耗时操作。大多数情况下,当程序退出时,子线程也许会正常退出。这时,虽然抱着侥幸心理,但隐患依然存在,也许在极少数情况下,就会出现Crash。原创 2017-03-16 13:20:00 · 50139 阅读 · 2 评论 -
Qt基础之十四:线程同步
虽然线程的目的是允许代码并行运行,但有时线程必须停止并等待其他线程。例如,如果两个线程试图同时写入同一个变量,则结果是未定义的。强制线程彼此等待的原则称为互斥。这是保护共享资源(如数据)的常用技术。Qt中的提供了多种线程同步方式,如下表所示Qt提供了同步相关的辅助类—QMutexLocker、QReadLocker和QWriteLocker,这样就可以更容易地使用QMutex和QReadWriteLock了。它们在构建资源时锁定资源,在销毁资源时自动解锁资源。原创 2022-12-31 14:26:35 · 5491 阅读 · 0 评论 -
Qt基础之十三:Threads和QObjects
run()是线程的入口,就像main()对于应用程序的作用。QThread中对run()的默认实现调用了exec(),从而创建一个QEventLoop对象,由其处理该线程事件队列(每一个线程都有一个属于自己的事件队列)中的事件。由此可见,exec()在其内部不断做着循环遍历事件队列的工作,调用QThread的quit()或exit()方法使停止工作,尽量不要使用terminate(),该方法过于粗暴,造成资源不能释放,甚至互斥锁还处于加锁状态。原创 2016-10-11 09:04:59 · 30172 阅读 · 3 评论 -
Qt基础之十二:Qt多线程基础
每个程序在启动时都有一个线程,这个线程被称为“主线程”(在Qt应用程序中也称为“GUI线程”)。Qt GUI必须在主线程中运行。所有widgets和一些相关的类,例如QPixmap,都不能在辅助线程中工作。辅助线程通常被称为“工作线程”,因为它用于减轻主线程的工作负担。原创 2016-05-14 15:15:48 · 6505 阅读 · 0 评论 -
Qt基础之十一:Qt程序只运行一个实例
让Qt应用程序只运行一个实例,实际上有两种方法,一种是使用QLocalServer和QLocalSocket类,另一种使用QSharedMemory类。这两种方法的本质都是进程间的通信。原创 2016-04-01 15:03:54 · 14663 阅读 · 3 评论 -
Qt基础之十:使用QVariant存储自定义类型
QVariant支持大部分常见的Qt数据类型互转,比如:除了基本的数据类型外,还可以使用Q_DECLARE_METATYPE()来向Qt的元系统声明自定义类型,比如说struct在使用QVariant传递自定义数据类型时,需要调用QVariant的setValue或fromValue方法,其中fromValue是静态方法取值的时候,不能使用toInt()、toString()等内建的方法, 需要用模版形式完整代码如下所示......原创 2017-08-02 13:13:37 · 8373 阅读 · 0 评论 -
Qt基础之九:子线程和GUI交互
但回调函数不一定运行在主线程中,因此我们需要将数据封装成事件,然后用postEvent添加到事件列表,接着就可以在主线程重写的event方法中处理该事件了。Qt基础之五:使用invokeMethod异步调用函数 https://blog.csdn.net/caoshangpa/article/details/79420547。C++面试题之为什么不能多线程直接操作GUI状态 https://blog.csdn.net/caoshangpa/article/details/78557639。原创 2022-11-18 17:39:58 · 6099 阅读 · 0 评论 -
Qt基础之八:父子对象关系
当创建一个新的Qt对象的时候,如果把另外一个Qt对象指定为这个对象的父对象,那么父对象就会在它的子对象链表中加入这个子对象的指针。在delete child1对象的时候,child1对象会自动的把自己从parent对象的子对象链表中删除,也就是说,在child1对象被delete完成之后,parent对象就只有一个子对象(child2)了。当delete一个父对象的时候,Qt的对象模型机制保证了会自动的把它的所有子对象,以及孙对象,等等,全部delete,从而保证不会有内存泄漏的情况发生。原创 2017-07-16 17:16:18 · 7062 阅读 · 1 评论 -
Qt基础之七:事件循环
局部事件循环几乎包含主事件循环的所有功能(当局部事件循环被激活时,GUI界面的响应相关事件已经被包含到局部循环中了),所以当在主线程中启动各种exec()(比如QEventLoop::exec())时,虽然会中断main函数中的QApplication::exec(),但界面还是可以正常响应,不会出现卡住的现象,只有当局部事件循环跳出 exec() 后,父层事件循环才能继续循环下去。这里不的不说一下Qt事件和windows消息的关系,Qt的事件是windows的底层消息封装而成的。原创 2016-05-14 15:23:22 · 6840 阅读 · 0 评论