草上爬
专注技术,热爱分享
展开
-
Qt基础之四十九:Qt属性系统(Property System)
属性使用的自定义类型需要使用Q_DECLARE_METATYPE()宏进行注册,以便将其值存储在QVariant对象中。这使得它们既适用于在类定义中使用Q_PROPERTY()宏声明的静态属性,也适用于在运行时创建的动态属性。原创 2025-02-24 23:30:34 · 307 阅读 · 0 评论 -
Qt基础之四十八:按钮为何会有点击效果
按钮为何会有点击效果?Qt窗口绘制原理;QPushButton绘制原理。原创 2024-10-03 17:28:12 · 1552 阅读 · 0 评论 -
Qt基础之四十七:管理员权限
在Windows系统中,以管理员身份运行的意思是,用系统管理最高权限运行程序。一般来说,只有当某些操作涉及系统保护区域时,才会需要用户授权管理员运行。如此一来,程序、命令在运行过程中,就有了足够权限,更改系统设置或注册表。原创 2024-09-25 23:38:47 · 2343 阅读 · 0 评论 -
Qt基础之四十六:Qt界面中嵌入第三方程序的一点心得
本文主要讲解QWidget和QWindow的区别,以及如何在QWidget中嵌入第三方程序,并完美解决在QWidget中嵌入某些程序(比如Qt程序)时出现的白边问题。原创 2024-04-21 18:54:25 · 5919 阅读 · 14 评论 -
Qt基础之四十五:Qt国际化(I18N)
国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),这种奇葩的缩写方式,让我想起了NBA球星“字母哥”。下面看下Qt实现的动态语言切换效果。原创 2023-12-31 20:56:04 · 4496 阅读 · 13 评论 -
Qt基础之四十三:Qt智能指针(QPointer、QSharedPointer、QWeakPointer和QScopedPointer)
Qt智能指针(QPointer、QSharedPointer、QWeakPointer和QScopedPointer)原创 2023-12-30 00:10:13 · 4319 阅读 · 1 评论 -
Qt基础之四十二:QMap、QHash的实现原理和性能对比
QMap、QHash的实现原理和性能对比:红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树为了保证其最长路径中节点个数不会超过最短路径节点个数的两倍,具有以下五个特性:(1)每个结点不是红色就是黑色(2)根节点是黑色的(3)如果一个节点是红色的,则它的两个孩子结点是黑色的。原创 2023-12-15 18:56:50 · 5429 阅读 · 0 评论 -
Qt基础之四十一:记一次QVector的bad alloc问题追踪
记一次QVector的bad alloc问题追踪原创 2023-12-07 23:50:03 · 5562 阅读 · 1 评论 -
Qt基础之四十:Qt Installer Framework(QtIFW)的编译、使用和实现原理
Qt Installer Framework(QtIFW)的编译、使用和实现原理原创 2023-12-02 15:01:06 · 6450 阅读 · 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 · 7766 阅读 · 0 评论 -
Qt基础之三十八:快捷键
一.按钮的快捷键二.菜单项的快捷键1.菜单栏菜单2.快捷菜单三.QShortcut四.快捷键冲突的处理五.全局快捷键原创 2023-10-22 23:02:00 · 5213 阅读 · 0 评论 -
Qt基础之三十七:是否发生复制?浅谈参数在信号-槽中的传递
当信号的参数是对象的常引用,且槽的参数也是对象的常引用,那么这个对象会复制多少次呢?信号和槽的direct和queued连接方式有何不同?如果信号和槽的参数都按值传递,会发生什么变化呢?这个问题通常会在项目的某个时刻(比如说性能优化时)提及,但Qt文档对此只字未提。关于有一个很好的讨论,不过需要读者从所有评论中选择正确的答案。因此,下面让我们系统地讨论参数是如何在信号和槽间传递的。翻译 2023-10-03 15:58:33 · 5346 阅读 · 0 评论 -
Qt基础之三十六:异常处理
本文将介绍如何在Qt中使用try...catch和调试dump文件来处理异常。Qt版本5.12.6。原创 2023-05-28 10:39:09 · 11603 阅读 · 0 评论 -
Qt基础之三十五:Qt中文乱码探索
Qt中文乱码看这一篇就够了先说个小技巧:Qt Creator支持显示源文件编码格式右上角点UTF-8,会弹出“文件编码”对话框我的开发环境是Win10 Qt5.12.6 VS2017,IDE是Qt Creator。原创 2023-04-07 00:13:12 · 7198 阅读 · 1 评论 -
Qt基础之三十四:QTcpSocket和QTcpServer源码分析
QTcpSocket和QTcpServer源码分析原创 2023-04-03 23:47:20 · 5987 阅读 · 0 评论 -
Qt基础之三十三:海量网络数据实时显示
开发中我们可能会遇到接收的网络数据来不及显示的问题。最基础的做法是限制UI中加载的数据行数,这样一来可以防止内存一直涨,二来数据刷新非常快,加载再多也来不及看。此时UI能看到数据当前处理到什么阶段就行,实时性更加重要,要做数据分析的话还得查看日志文件。这里给出UDP+QListView和TCP+QPlainTexEdit两种实现方案。原创 2023-03-19 11:34:11 · 7846 阅读 · 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 · 8127 阅读 · 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 · 6476 阅读 · 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 · 6170 阅读 · 1 评论 -
Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用
无意中从网络获取一份俄罗斯方块源码,基于图形视图框架(Graphics View Framework)实现的。当然源码的核心从来都不是界面,而是方块的移动、变形和消除等算法。源码非常完整,注释详细,经改动后已能在Qt5中运行,下面是运行效果,背景音乐和音效也是有的。原创 2023-02-21 22:45:40 · 6598 阅读 · 2 评论 -
Qt基础之二十六:Qt绘图系统(Paint System)
通过从QPaintDevice类派生并重新实现QPaintDevice:paintEngine()函数,即可添加一个新的绘图设备。在paintEngine中要告知QPainter应该使用哪种绘图引擎在该设备上绘制。要真正能够在自定义绘图设备上绘制,此绘图引擎必须是从QPaintEngine类派生的自定义绘图引擎。原创 2023-02-11 23:15:13 · 7010 阅读 · 0 评论 -
Qt基础之二十三:反射(Reflection)
不同于boost这样的模板库,Qt利用自带的Meta-Object Compiler(moc)来生成额外的C++代码,这些代码实现了Qt程序所必须的元数据对象,可以说Qt是基于C++的一种扩展。反射是指程序在运行时动态获取对象属性与方法的一种机制,即编译器需要将类型信息(属性类型与偏移地址以及成员函数的地址等信息)编译到程序文件中,当程序运行时将这些信息加载到内存中去,做到运行时只根据对象的地址或引用就可以获取到对象的类型信息,从而利用这些信息达到修改或重建对象的目标。☆在运行时调用对象的方法;原创 2023-01-25 13:26:33 · 10775 阅读 · 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 · 6846 阅读 · 2 评论 -
Qt基础之二十:进程间通信
进程间通信(IPC:Inter-Process Communication),就是在不同进程之间传播或交换信息。那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件。除此以外,那就是双方都可以访问的外设了。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息。原创 2023-01-08 14:59:03 · 7549 阅读 · 0 评论 -
Qt基础之十八:WebEngine与JavaScript交互
Qt从5.6开始就用Qt Webengine替换了Qt WebKit,据说加载速度较Qt WebKit更快。需在pro中添加QT += webenginewidgets。原创 2023-01-04 22:41:19 · 6157 阅读 · 0 评论 -
Qt基础之十六:QtConcurrent和QThreadPool
QtCurrent模块能处理一些常见的并行计算:map、filter和reduce。它们返回一个QFuture对象,该对象可用于获取函数执行的结果。QFuture还可用于查询计算进度和暂停/恢复/取消计算。为了方便起见,QFutureWatcher可以通过信号和插槽与QFuture进行交互。QtCurrent的map、filter和reduce算法自动将计算分布到所有可用的处理器核上,因此,当QtCurrent在多核系统上更有优势。原创 2023-01-02 09:48:23 · 5879 阅读 · 1 评论 -
Qt基础之十四:线程同步
虽然线程的目的是允许代码并行运行,但有时线程必须停止并等待其他线程。例如,如果两个线程试图同时写入同一个变量,则结果是未定义的。强制线程彼此等待的原则称为互斥。这是保护共享资源(如数据)的常用技术。Qt中的提供了多种线程同步方式,如下表所示Qt提供了同步相关的辅助类—QMutexLocker、QReadLocker和QWriteLocker,这样就可以更容易地使用QMutex和QReadWriteLock了。它们在构建资源时锁定资源,在销毁资源时自动解锁资源。原创 2022-12-31 14:26:35 · 5615 阅读 · 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 · 6400 阅读 · 0 评论 -
Qt基础之四:Qt信号与槽机制原理及优缺点
在GUI编程中,当我们改变一个控件,通常希望其他控件被通知到。更一般的,我们希望任意对象之间能够通信。例如,如果我们点击了“关闭”按钮,我们希望窗口的close()函数被调用。其他工具包使用回调来实现这种通信。回调函数是一个指向函数的指针,所以如果你想要一个处理函数通知你一些事件,你可以将一个指向另一个函数(回调函数)的指针传递给处理函数。处理函数然后在适当的时候调用回调函数。但回调可能不太直观,而且在确保回调参数的类型正确性方面可能会遇到问题。原创 2022-11-12 09:09:07 · 7446 阅读 · 0 评论 -
Qt基础之六:Model/View架构
模型/视图是一种用于从视图中分离数据的技术。标准widgets不是为从视图中分离数据而设计的,这就是为什么Qt有两种不同类型的widgets。这两种类型的widgets看起来相同,但它们与数据的交互方式不同。☆标准widgets的数据是widgets的一部分☆Model/Viewwidgets操作View外部的数据(model)......原创 2022-07-20 18:55:39 · 6864 阅读 · 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 · 8444 阅读 · 0 评论 -
Qt基础之三:Qt元对象系统
这个函数返回 QMetaObject 元对象类的实例,通过它,你就获得了 Qt 类的反射的能力:获取本对象的类型之类,而这一切,都不需要 C++ 编译器的 RTTI 支持。构建项目时,moc工具读取 C++ 源文件,当它发现类的定义里有 Q_OBJECT 宏时,它就会为这个类生成另外一个包含有元对象支持代码的 C++ 源文件,这个生成的源文件连同类的实现文件一起被编译和连接。这是一个空白的类,什么都没有实现。2.在类的头文件中声明 Q_OBJECT宏,使得类可以使用元对象的特性,如动态属性、信号与槽。原创 2018-04-28 15:49:51 · 11615 阅读 · 3 评论 -
Qt基础之四十四:qmake构建原理
qmake构建原理。当一个项目很小的时候,直接使用编译器、链接器等编译工具,就可以把代码构建成程序。当项目越来越大时,除了需要调用编译工具编译程序,还需要做很多事情,例如:☆配置编译工具☆设置编译选项☆添加头文件☆添加第三方库☆添加资源文件☆自动增量编译,自动检测文件修改☆链接程序☆软件自动部署☆自动化测试等等完成这些步骤,需要调用几个甚至几十个工具来完成。这导致构建软件的任务变得非常繁琐,如果每次构建都需要开发者手动逐个调用工具完成,就会产生大量的、机械的重复性劳动。原创 2018-04-04 16:58:24 · 10573 阅读 · 1 评论 -
Qt基础之五:使用invokeMethod异步调用函数
在主线程中如果执行比较耗时的任务,但是又不想单独开子线程来处理,不妨试试Qt中提供QMetaObject::invokeMethod方法,该方法支持函数的异步调用,这样就会在界面显示后去执行,而不会卡主主界面这里MyMethod就是被调用的函数名,如果MyMethod带参数且有返回值,如下所示需要注意的是,如果第三个参数使用Qt::QueuedConnection,即异步调用,将无法获取返回值,因为此连接方式只是负责把事件交给事件队列,然后立刻返回,所以函数返回值就无法确定了invokeMet原创 2018-03-02 10:45:48 · 12880 阅读 · 0 评论 -
Qt基础之一:QObject
从 QObject class 的定义中,我们可以看到,这第二个构造函数是被定义为protected 类型的,这说明,这个构造函数只能被继承的class使用,而不能使用这个构造函数来直接构造一个QObject对象,也就是说,如果写一条下面的语句, 编译的时候是会失败的,在 QT 4.4 中,类成员变量声明的出发点没有变化,只是在具体的实现手段上发生了非常大的变化,在 QT 4.4 中,使用了非常多的宏来做事,这凭空的增加了理解 QT source code 的难度,不知道他们是不是从MFC学来的。转载 2018-01-19 13:57:59 · 6921 阅读 · 0 评论 -
Qt基础之二十七:访问SQLite数据库
Qt通过不同的数据库驱动来实现访问不同的数据库,QSqlDriver是一个抽象类,是所有数据库驱动类的基类。Qt支持访问很多不同的数据库,例如Sqlite,MySQL,SqlServer等,但是Qt具体都支持哪些数据库呢?在QtAssistant中输入QSqlDatabase,可以看到Qt目前支持的所有数据库。.........原创 2017-12-19 17:33:40 · 8434 阅读 · 1 评论 -
Qt基础之二:Qt的信号与槽连接方式(第五个参数)
这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少),但是不能说信号根本没有这个数据,你就要在槽函数中使用(就是槽函数的参数比信号的多,这是不允许的)。5.在同一个线程中,当一个信号被emit发出时,会立即执行其槽函数,等槽函数执行完毕后,才会执行emit后面的代码,如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序是按照它们链接时的顺序执行的。当第三方库中也有信号/槽函数机制时,这时候又需要使用Qt的信号和槽函数机制。原创 2017-11-14 10:06:36 · 6764 阅读 · 0 评论 -
Qt基础之十:使用QVariant存储自定义类型
QVariant支持大部分常见的Qt数据类型互转,比如:除了基本的数据类型外,还可以使用Q_DECLARE_METATYPE()来向Qt的元系统声明自定义类型,比如说struct在使用QVariant传递自定义数据类型时,需要调用QVariant的setValue或fromValue方法,其中fromValue是静态方法取值的时候,不能使用toInt()、toString()等内建的方法, 需要用模版形式完整代码如下所示......原创 2017-08-02 13:13:37 · 8633 阅读 · 0 评论 -
Qt基础之八:父子对象关系
当创建一个新的Qt对象的时候,如果把另外一个Qt对象指定为这个对象的父对象,那么父对象就会在它的子对象链表中加入这个子对象的指针。在delete child1对象的时候,child1对象会自动的把自己从parent对象的子对象链表中删除,也就是说,在child1对象被delete完成之后,parent对象就只有一个子对象(child2)了。当delete一个父对象的时候,Qt的对象模型机制保证了会自动的把它的所有子对象,以及孙对象,等等,全部delete,从而保证不会有内存泄漏的情况发生。原创 2017-07-16 17:16:18 · 7181 阅读 · 1 评论 -
Qt基础之十五:优雅地结束线程
如果一个线程运行完成,就会结束。可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它。不恰当的中止往往会引起一些未知错误。比如:当关闭主界面的时候,很有可能次线程正在运行,这时,就会出现如下提示:这个问题在使用线程的过程中经常遇到,尤其是耗时操作。大多数情况下,当程序退出时,子线程也许会正常退出。这时,虽然抱着侥幸心理,但隐患依然存在,也许在极少数情况下,就会出现Crash。原创 2017-03-16 13:20:00 · 51299 阅读 · 2 评论