从 stringstream 中获取拼接后的 string

需求 如何从 stringstream 中获取多次拼接后的 string, 直接使用 >> 效果并不好. 解决 使用 stringstream 的 str() 这个类函数。 stringstream ss; string s = ""; ss << "123"; ss << "456"; s = ss.str(); 参考 c++ stringstream(老好用了)

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

QT Text 相关 widget 追加文本不换行

需求 正常在 QTextEdit QTextBrowser 中使用 append 添加新内容,都是自动换行的,如果不希望自动换行怎么办? 解决 其实很简单,使用 insertPlainText 这个方法即可。 textBrowser->insertPlainText("hello "); textBrowser->insertPlainText("world"); insertPlainText接口是在当前光标插入文本(光标一般默认在末尾),不自动换行,所以会打印: hello world 参考 QTextEdit QTextBrowser追加文本不换行

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

emacs cpp 使用 tags

需求 代码自动补全需要 tags. 解决 生成 tags tags 生成工具 使用 gtags 生成 tags, 如果没有 gtags=,需要安装 =global. sudo apt install global 生成 tags # dump index files to directory ~/obj if 3rd party library directory is read only cd /usr/include && MAKEOBJDIRPREFIX=~/obj gtags --objdir cd /usr/src/linux/include && MAKEOBJDIRPREFIX=~/obj gtags --objdir # # above two command lines are same as below two command lines # mkdir -p ~/obj/usr/include && cd /usr/include && gtags --objdir=~/obj/usr/include # mkdir -p ~/obj/usr/linux/include && cd /usr/linux/include && gtags --objdir=~/obj/usr/linux/include ....

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

emacs tab 设置为4个空格

需求 默认的 emacs 换行是两个空格,需要改为4个空格,并且 tab 也是4个空格。 解决 只需要在 el 或者 org 配置文件中添加如下内容: ;; cc mode style, table instead of spaces (setq c-default-style "linux" c-basic-offset 4 tab-width 4 indent-tabs-mode t) 参考

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

使用智能指针替代裸指针

需求 希望使用智能指针,能够尽量减少内存泄漏 解决 智能指针比较适合在局部变量领域,在生命周期结束时,会自动释放。 定义 std::unique_ptr<QSerialPort> port_ = nullptr; std::unique_ptr<int[]> buf_ = nullptr; std::shared_ptr<int> data_ = nullptr; std::weak_ptr<int> weak_ = nullptr; 赋值 port_ = make_unique<QSerialPort>(); // 未初始化 buf_ = make_unique<int[]>(new int[10]); // 初始化为 0 buf_ = make_unique<int[]>(new int[10]()); buf_ = make_unique<int[]>(new int[10]{}); // shared data_ = make_shared<int>(); // weak 必须绑定 shared weak_ = data_; 使用 -> 这个是调用指针指向的对象的相关操作 . 这个是智能指针自身的一些操作 直接使用 shared_ptr 指针有可能会产生循环引用的问题,导致死锁,无法释放。建议使用 weak_ptr 来配合 shared_ptr. 注意 weak_ptr 无法单独存在并使用。 weak_ptr 在使用的时候,需要通过 lock 来获取 shared_ptr 对象,如果相应的内存已经释放,那么会返回 nullptr, 可以通过这个判断内存是否有效。 weak_ptr 本身不会增加 shared_ptr 的引用次数。 释放 释放有好几种方法,最简单的就是第一种。...

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

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

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

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

定义可变参数的函数的宏

需求 在 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