QT 在非多线程的情况下处理耗时事务

需求 在 qt 中既需要处理耗时任务,又不想使用多线程。 解决 可以在处理长时间耗时任务时,在耗时任务中周期性的调用 qApp.processEvents();, 这样可以让 qt 间断性的处理界面事务。比较推荐的是配合使用 QProgressDialog, 这样可以有进度条提示用户。代码如下: bool MyApp::writeFile(const QString &filename) { QFile file(filename); ... QApplication::setOverrideCursor(Qt::WaitCursor); QProgressDialog progress; progress.setWindowTitle(tableData->sNameCH); progress.setLabelText(QStringLiteral("数据保存中,请稍候...")); //progress.setCancelButton(0);//不显示“取消”按钮 progress.setCancelButtonText("取消"); progress.setRange(0,rowCount ); progress.setModal(true); //此处没有调用show()来显示,是因为QProgressDialog会自动决定是否显示 //如果时间过短,就不会显示。 for(int r = 0; r != rowCount; ++r) { progress.setValue(row); //如果用户单击了“取消”,就取消保存文件,并删除该文件。 if(progress.wasCanceled) { file.remov(); return false; } for(int c = 0; c != colCount; ++c) { out << table(r,c); qApp.processEvents(); } } QApplication::restoreOverrideCursor(); } 参考 Qt 如何处理密集型耗时的事情 QApplication::processEvents的作用

<span title='2023-02-20 16:17:00 +0800 CST'>2023-02-20</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;70 words&nbsp;·&nbsp;RamLife

优化冒泡排序

需求 需要写一个优化后的冒泡排序。 解决 为了简化代码,并且省去控制用的 flag,可以每次只排列剩余中的最小的,这 样可以使用 i 来同时控制排列的范围和当前最小的位置,使用 j 来控制进行比较的位置。 需要注意: i 的表示控制排列的范围和当前最小位置,所以 i 的取值不包含最后一个数,毕竟比较至少要有两个数才能比较。 j 是进行比较的数值,所以 j 是从 i 的后一个数开始,直到最后一个数。 public static void bubbleSort(float[] src) { for (int i = 0; i < src.length - 1; i++) { for (int j = i + 1; j < src.length; j++) { if (src[i] > src[j]) { float tmp = src[i]; src[i] = src[j]; src[j] = tmp; } } } }

<span title='2023-02-20 07:53:00 +0800 CST'>2023-02-20</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;70 words&nbsp;·&nbsp;RamLife

定义可变参数的函数的宏

需求 在 Linux 平台下运行程序时,需要通过 syslog 打印日志,syslog 本身是可变参数的函数,所以需要一个可变参数的宏来定义在 linux 平台下的函数。 解决 在 C++ 中,可变参数宏的写法是: #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__), 满足需求的代码如下: #ifdef Q_OS_LINUX #define LOG(priority, format, ...) syslog(priority, format, ## __VA_ARGS__) #else #define LOG(priority, format, ...) #endif 在 C 中,写法是: #define debug(format, ...) fprintf(stderr, fmt, __VA_ARGS__) 在 GCC 中,写法是: #define debug(format, args...) fprintf (stderr, format, args) 参考 不定参数的宏 函数 整理:C/C++可变参数,“## __VA_ARGS__”宏的介绍和使用 c/c++巧用宏计算不定参数个数【不定参数】【宏】【#define】

<span title='2023-02-15 18:23:00 +0800 CST'>2023-02-15</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;63 words&nbsp;·&nbsp;RamLife

QT C++ 识别当前操作系统平台,并编译相应代码

需求 需要在 Qt 中检测当前的操作系统平台具体是 win 还是 linux,然后根据不同的平台执行不同的代码。比如在 linux 平台可以使用 syslog 解决 #ifdef Q_OS_LINUX #include <syslog.h> #endif #ifdef Q_OS_WIN #endif #ifdef Q_OS_OSX #endif #ifdef Q_OS_LINUX openlog(NULL, LOG_CONS | LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_LOCAL0); setlogmask(LOG_UPTO(LOG_MASK_BUILD)); #endif syslog(LOG_DEBUG, "%s: %d: %s --> class construct", __FILE__, __LINE__, __FUNCTION__); 参考 Qt判断当前系统 QT C++识别当前操作系统

<span title='2023-02-14 09:34:00 +0800 CST'>2023-02-14</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;49 words&nbsp;·&nbsp;RamLife

C 语言 offsetof

需求 offsetof 了解 解决 以前是直接自定义 offsetof 的宏,来获取结构体当中的成员偏移。类似于下面这样: #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) 后来才发现,原来 c 语言里面早就有这个了,直接 #include <stddef.h> 就可以使用了。 参考 C 库宏 - offsetof()

<span title='2023-02-03 16:26:00 +0800 CST'>2023-02-03</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;23 words&nbsp;·&nbsp;RamLife

C 语言中 typedef 用法

需求 学习了解 typedef 在 c 语言中的用法 解决 基本解释 typedef 为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型( int, char 等)和自定义的数据类型( struct 等)。 在编程中使用 typedef 目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。 至于 typedef 有什么微妙之处,请你接着看下面对几个问题的具体阐述。 <!–more–> typedef & 结构的问题 当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明: typedef struct tagNode { char *pItem; pNode pNext; } *pNode; 答案与分析 typedef的最简单使用 typedef long byte_4; 给已知数据类型long起个新名字,叫byte_4。 typedef与结构结合使用 typedef struct tagMyStruct { int iNum; long lLength; } MyStruct; 这语句实际上完成两个操作: 定义一个新的结构类型. 分析: tagMyStruct 称为“tag”,即“标签”,实际上是一个临时名字, struct 关键字和 tagMyStruct 一起,构成了这个结构类型,不论是否有 typedef ,这个结构都存在。 我们可以用 struct tagMyStruct varName 来定义变量,但要注意,使用 tagMyStruct varName 来定义变量是不对的,因为 struct 和 tagMyStruct 合在一起才能表示一个结构类型。 struct tagMyStruct { int iNum; long lLength; }; typedef 为这个新的结构起了一个名字,叫 MyStruct 。因此, MyStruct 实际上相当于 struct tagMyStruct ,我们可以使用 MyStruct varName 来定义变量。 typedef struct tagMyStruct MyStruct; 结构体指针 C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于 typedef 的应用。...

<span title='2010-12-01 22:40:00 +0800 CST'>2010-12-01</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;365 words&nbsp;·&nbsp;RamLife

C 语言结构体数组,函数指针实现简单的菜单选项功能

需求 需要通过 C 语言实现简单的数码管或者段码液晶屏的简单的菜单选项功能 解决 结构体申明和定义 在 .h 文件中申明: typedef struct value_channel { unsigned char dir; unsigned int ADCValue[128]; }v_c; extern v_c value[4]; 在 .c 文件中定义 v_c value[4]; 函数指针 定义一个函数指针 void ( * fp)(void); 函数功能和跳转 void fun_start_01(void); { ...... } void fun_start(void) { switch(cs) { case 01: fp=fun_start_01; break; } } 在菜单调用的地方使用 ( * fp)(); 即可调用相应的菜单项。 函数地址 函数地址也可以放在数组中来调用: typedef void( * dis_turn)(void); void dis_turn_1(void) void dis_turn_2(void) dis_turn dis[]={dis_turn_1,dis_turn_2}; main() { dis[0](); dis[1](); } 实现菜单 typedef void(*FUN_P)(void);//(int Data) typedef struct Message_Item { unsigned char cStatus; FUN_P fnProcess; }MSG_ITEM; MSG_ITEM MSGMap[]={{0x00,fun_start},{0x01,fun_normal},{0x02,fun_set0},{0x03,fun_gas},{0x04,fun_set}}; void SearchMSGMAP(void) //(unsigned char cStatus) { unsigned char n=0; for(n=0;n<UBOND(MSGMap);n++) { if(MSGMap[n]....

<span title='2010-12-01 22:18:00 +0800 CST'>2010-12-01</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;108 words&nbsp;·&nbsp;RamLife