QT 警告: QObject: Cannot create children for a parent that is in a different thread

需求 在运行 qt 程序时,出了相应的警告: QObject: Cannot create children for a parent that is in a different thread. (Parent is QThread(0xb95feffd70), parent's thread is QThread(0x1d3729aef20), current thread is QThread(0xb95feffd70) 解决 这个其实就是在子线程中,使用了主线程的对象,并创建子对象,所以出的警告。解决的方法也有几种: 子线程创建子对象 简单说,就是在子线程中先获取主线程的相应参数,然后创建出需要的对象,这样的话,在需要创建子对象的时候,也是在同一个线程。这种方法最简单,就是代码上可能啰嗦一点。 不指定父对象 对象创建时,不指定父对象,也就是不使用 this 来指定,留空即可。如果碰到一些调用的库函数内部创建对象,这种方法就不好使了。 使用 moveToThread 绑定相应的线程 调用 QObject 的成员函数 moveToThread, 绑定到对应的线程上去。下面是几个例子: ThreadTest2 thread2; thread2.moveToThread(&thread2); thread2.start(); 上面这个例子,thread2 把自己从主线程绑定到子线程,这样在 ThreadTest2 这个类内部创建的对象也就转移到子线程上去了。 class Controller : public QObject { Q_OBJECT ... private: QThread thread; }; Controller::Controller(QObject* parent) : QObject(parent) { Worker *worker = new Worker(); worker->moveToThread(&thread); ....

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

[转] C++ 或 QT 判断当前模式是Debug还是Release模式

需求 在构建版本的时候,需要在 debug 和 release 版本中有不一样的地方,这时候就需要使用宏来自动识别并展开对应的语句。 解决 C++ #ifdef DEBUG cout << "Debug!" << endl; #else cout << "Release!" << endl; #endif Qt #ifdef QT_DEBUG cout << "Debug!" << endl; #else cout << "Release!" << endl; #endif 参考 C++ 或 QT 判断当前模式是Debug还是Release模式

<span title='2023-03-06 15:13:00 +0800 CST'>2023-03-06</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;42 words&nbsp;·&nbsp;RamLife

syslog 使用及宏

需求 syslog 虽然使用起来很方便,但是直接使用有几个问题: 虽然有日志信息,但是不够全面不方便定位 那么多的日志都混在一起,没有重点,调试时不方便 debug 和 release 时,日志应该不一样。 解决 日志信息更丰富 syslog 可以使用 __FILE__, __LINE__, __FUNCTION, 这几个来标识出当前的日志是在那个文件,第几行,哪个函数输出的。 syslog(LOG_DEBUG, "%s: %d: %s --> class construct", __FILE__, __LINE__, __FUNCTION__); 使用宏来开关日志 下面这个是普通替代的宏,可以用于开关日志. #ifdef xxx #define LOG(priority, format, ...) syslog(priority, format, ## __VA_ARGS__) #else #define LOG(priority, format, ...) #endif 使用宏来减少输入 但是每条日志都要这样写,就太麻烦了,我们可以使用宏来解决这个问题: #define LOG(priority, format, ...) syslog(priority, "%s: %d: %s --> "#format, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__) LOG(LOG_DEBUG, "class construct"); 上面这条宏,我们在使用时,不需要显式的写出相关的参数,宏展开的时候,会自动帮我们加上这些参数,日志会包含文件名,行号,函数名. 使用宏增加日志等级 当多条日志信息在一起的时候,比较难抓住重点,虽然可以使用搜索,但是终归没有那么方便。我们可以通过宏给日志消息里面附上对应的等级,也方便后期维护时使用脚本进行解析。 #define LOG(priority, format, ....

<span title='2023-03-06 15:02:00 +0800 CST'>2023-03-06</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;223 words&nbsp;·&nbsp;RamLife

QMutex 和 QWaitCondition 配合用于多线程

需求 多线程同步时,需要线程能够被外部唤醒,从而按照一定的顺序来执行。 解决 同步可以使用 QWaitCondition 先让线程睡眠,然后在必要的时候从外面唤醒 线程即可。但是 QWaitCondition 所在的线程必须先使用 QMutex 上锁才行, QWaitCondition 会先阻塞线程,然后把锁释放,再等待唤醒,唤醒可以对 QWaitCondition 的对象使用 wakeAll() 或者 wakeOne() , 唤醒后,锁会自动回来,所以别忘了最后的解锁. QMutex 除了直接的 lock, 还可以使用 QMutexLocker 自动上锁,并在生命周期结束后自动解锁。 m_mutex.lock(); m_cond.wait(&m_mutex); ... m_mutex.unlock(); const QMutexLocker locker(&m_mutex); ... m_cond.wakeOne(); 参考 Qt互斥锁(QMutex)、条件变量(QWaitCondition)理解+QMutex实现多线程循环输出ABC(含源码+注释) QT线程QMutex和 QWaitCondition 结合使用的例子

<span title='2023-02-27 19:13:00 +0800 CST'>2023-02-27</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;40 words&nbsp;·&nbsp;RamLife

org-mode 显示图片

需求 在 org-mode 中显示本地图片 解决 输入图片路径,如下所示: [[./img/a.jpg]] 显示图片只需要 C-c C-x C-v 也就是 org-toggle-inline-images 就可以了,或者设置 org-startup-with-inline-images, 让启动时就生效图片. 参考 org-mode图片支持 图文混排:Emacs Org中显示图片 在Org Mode中插入和使用图片 org-mode插入图片的方法 org mode 嵌入图片 Org-mode导出html为什么没显示图片?

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

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

Android Studio 统计项目代码行数

需求 编写注册资料中,有一项是统计代码行数,所以需要获取在 android studio 中项目的代码行数,正常来说代码行数包含源码行数和注释行数。 解决 安装插件 在 android studio 中,依次点击 File -> Settings -> Plugins, 然后搜索 statistic, 点击安装。 使用插件 在屏幕下方 logcat 那一行,找到 statistic, 打开后,点击左上角的 refresh 第一个是 overview, 可以根据自己的需要点击 java 页面,就可以看到总的代码行数了。 参考 Android Studio 统计代码行数插件—{Statistic} Android studio统计代码行数 Android Studio 统计项目代码总行数

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

双屏位置更换

需求 当电脑的两个屏幕的实体位置发生了变化,希望鼠标在移动时,也能在正确的方向和位置出入双屏. 解决 桌面右键, 选择 display settings. 在 display 的界面中, 可以使用鼠标拖拽两个屏幕,使得他们的相对位置符合当前的实际位置. 点击 apply 即可 参考 使用扩展屏时设置鼠标切换到另一屏幕的方向

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

清除已有网络驱动器

需求 当网络驱动器的登陆名,密码等修改之后,无法登陆时,需要清除已有的网络驱动器,并重新创建,如果有大量的映射需要删除,一个一个删比较麻烦。 解决 使用 ctrl + r, 打开运行窗口,输入 net use * /del, 然后在窗口中输入 y 即可清除所有已有的网络驱动器。 参考 关于windows映射网络驱动器,登录时重新连接

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