QT qprocess 调用进程,输出到文件,实时输出

需求 使用 QProcess 调用 ping, 并输出结果到文件,或者实时输出显示。 解决 调用进程 std::shared_ptr<QProcess> process_ = nullptr; process_ = std::make_shared<QProcess>(this); process_->start("ping www.baidu.com"); if (process_ != nullptr) { //process_->close(); process_->kill(); process_->waitForFinished(); process_ = nullptr; } close() 可以直接关闭子进程 kill() 用于向子进程发送 SIGKILL, 然后通过 waitForFinished() 来等待子进程退出。 输出到文件 在 start() 之前: process_->setStandardOutputFile("out.txt"); 实时输出显示 在 start() 之前: process_->setReadChannel(QProcess::StandardOutput); connect(process_.get(), &QProcess::readyRead, [=](){ qDebug() << process_->readAllStandardOutput(); }); 记得使用 closeReadChannel() 来关闭读取通道。 参考 QT QProcess 重定向问题 QProcess开启外部程序,实时获取该程序的标准输出 QProcess快速实现外部程序调用 Qt开发之路34—QProcess重定向子进程的日志输出 QT: 使用QProcess启动进程并实时获取标准输出 Qt 之启动外部程序

2023-08-09 · 1 min · 68 words · RamLife

QT 信号槽和回调函数的区别

需求 信号槽和回调函数区别 解决 方便 信号和槽相对更加方便。 回调函数和接口在每次使用的时候,都需要额外判断函数指针是否为空。 当需要回调多个函数的时候,还需要管理多个函数指针。 当调用和被调用中间隔了几个类,回调就会很麻烦,需要把指针一路传递过去。 速度 回调函数和接口这样直接使用的明显会更加快速,信号和槽会慢一些。曾经出现一个问题,使用信号和槽在断开连接时只打印一次,使用回调函数会打印两次,经过调试发现,使用信号和槽在调试模式也会打印两次。初步判断是信号虽然触发了两次,但是因为时间过短,所以导致只执行了一次槽函数。 参考

2023-07-28 · 1 min · 11 words · RamLife

c++ 实现类似 java 的 interface

需求 cpp 实现类似 java 的 interface 解决 interface 关键字 因为 interface 所有声明默认都是 public=,所以选择 =struct. #define interface struct; #define implements public 使用 #include "Interface.h" Interface IBar { public: virtual ~IBar(){} virtual int getBarData() const = 0; virtual void setBarData(int nData) = 0; }; class Bar :public BasicBar,implements IBar { public: Bar(int x=0) : BasicBar(x) { } ~Bar(){} virtual int getBarData() const { std::cout <<"Get Bar!"; return 0; } virtual void setBarData(int nData) { } }; class DataAccess { // Construction & Destruction public: DataAccess() { } ~DataAccess() { } static IBar* createBar() { //返回对象给IBar接口 return(new Bar()); } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //IBar *bar = new Bar(); IBar *bar = DataAccess::createBar(); bar->getBarData(); delete bar; return a....

2023-07-28 · 1 min · 143 words · RamLife

c++ 工厂设计模式

需求 cpp 工厂模式 解决 https://zhuanlan.zhihu.com/p/83535678 https://zhuanlan.zhihu.com/p/83537599 参考

2023-07-28 · 1 min · 7 words · RamLife

c++ impl 使用接口类

需求 cpp impl ? 解决 impl 使用接口类有两种方式: 接口类只是作为一个壳,需要什么都是直接调用原来的类来实现 接口类是使用虚函数,实现类通过继承来实现 代理类 代理类非常简单,下面这个 WeightProxy 就是壳,具体的实现都在 Weight 里面。 #ifndef WEIGHTPROXY_H #define WEIGHTPROXY_H #include <string> #include <memory> class Weight; class WeightProxy { public: WeightProxy(); ~WeightProxy(); std::string GetInfo(); std::unique_ptr<Weight> m_proxy; }; #endif // WEIGHTPROXY_H #include "Weightproxy.h" #include "Weight.h" WeightProxy::WeightProxy() : m_proxy(new Weight()) { } WeightProxy::~WeightProxy() = default; std::string WeightProxy::GetInfo() { return m_proxy->GetInfo(); } #include <iostream> // std::streambuf, std::cout #include "Weightproxy.h" int main () { WeightProxy w; std::cout << w....

2023-07-27 · 1 min · 207 words · RamLife

c++ impl 使用指针实现即 pimpl

需求 cpp impl 是什么? 解决 impl 解决的问题 依赖太多,包含头文件过多,一个头文件修改,一堆源文件都需要重新编译,导致的编译时间过长。 库文件,不喜欢在头文件中暴露太多的内部成员变量等信息给使用着。 简单 pimpl // 使用Pimpl // 在头文件person.hpp中 #include <memory> class Person { public: Person(); private: // Person类的实现细节放置在该前向声明的实现类中。 struct Impl; // 指向实现类Impl的私有指针 std::unique_ptr<Impl> pimpl_; }; // 在源文件person.cpp中 #include "person.hpp" #include "basic_info.hpp" #include <string> #include <memory> struct Person::Impl { std::string name; std::string id; BasicInfo basic_info; }; Person::Person() : pimpl_(std::make_unique<Impl>()) {} 具体的成员变量放到 cpp 文件中,编译为库后,有以下好处: 就算需要修改包含的成员变量,也不需要修改头文件,那么编译的时候,只会编译这个 cpp 文件,其他依赖这个头文件的都不需要重新编译。 使用者并不能从头文件中发现成员变量的细节。 pimpl 更多细节 pimpl 在使用的时候,还会碰到很多需要注意的地方: 析构函数的实现需要完整的类型 移动赋值需要完整类型 移动构造需要完整类型 拷贝构造和拷贝赋值都需要完整类型 所以上面这些都需要放在 cpp 中实现。...

2023-07-27 · 1 min · 158 words · RamLife

QT QFutureWatcher 介绍

需求 QFutureWatcher ? 解决 QFutureWatcher 一般是搭配 QFuture, QtConcurrent 来使用,用于检测多线程异步执行计算的进度,方便在主线程上进行展示或者执行其他动作。 配置 watcher watcher_ = new QFutureWatcher<int>; connect(watcher_, &QFutureWatcher<int>::finished, this, &MainWindow::busy_job_finished); 调用子线程来执行 QtConcurrent::run 提供了最简单的子线程执行函数的方法。 auto future = QtConcurrent::run(this, &MainWindow::do_busy_job); watcher_->setFuture(future); int MainWindow::do_busy_job() { return 1; } 执行结果 void MainWindow::busy_job_finished() { // 若有需要, 关闭通知对话框 qDebug() << "busy job finished!"; qDebug() << "the returned value is: " << watcher_->result(); } 参考 在 QT UI 编程中使用 QtConcurrent 和 QFutureWatcher 执行并发任务 使用QFuture类监控异步计算的结果 Qt多线程编程之高级函数 QFutureWatcher:异步运行监视者 Qt多线程:QtConcurrent + QFuture + QFutureWatcher...

2023-07-23 · 1 min · 77 words · RamLife

QT QHash 介绍

需求 QHash ? 解决 QHash<Key, T> 是类似于 QMap 的键值对,但是与 QMap 的区别是: QHash 比 QMap 查找更快,但是所需空间更大。 QMap 默认键值升序排序, QHash 任意排序 QMap 键类型必须提供 operator<(), QHash 键类型必须提供 operator==() 和 qHash() 全局哈希函数。 参考 QT之QHash简介 Qt:QHash和QMap区别

2023-07-23 · 1 min · 31 words · RamLife

QT 警告 QObject::connect: Cannot queue arguments of type

需求 qt 程序在运行过程中,报了警告 QObject::connect: Cannot queue arguments of type 'qintptr' 解决 跨线程的信号和槽中,如果出现自定义的类型,那么就会报这个问题。解决也很简单。 在使用这个自定义类的信号和槽的类源文件中,增加头文件 #include <QMetaType>. 在这个类的构造函数中添加 qRegisterMetaType #include <QMetaType> TcpSocket::TcpSocket(qintptr socketDescriptor, QObject *parent) : QTcpSocket(parent), socketID(socketDescriptor) { qRegisterMetaType<qintptr>("qintptr"); this->setSocketDescriptor(socketDescriptor); ... } 参考 QObject::connect: Cannot queue arguments of type “xxx"的解决方案 Qt 线程间信号槽传递自定义数据类型(qRegisterMetaType的使用) QObject::connect: Cannot queue arguments of type…【已解决】

2023-07-23 · 1 min · 47 words · RamLife

QT QMetaObject 介绍

需求 QMetaObject ? 解决 QMetaObject 是 Qt 的元对象系统,里面保持了类的相关信息,主要的作用是为了在有指针的情况下,获取这个指针具体的类型信息,方便调试;另外也是 Qt 实现信号和槽的基础。毕竟 C++ 只有 dynamic_cast 用来试探子类型, typeid 只能获取类型名称,其他类型相关信息都不能获取。 由于C++是静态类型语言,有关类的信息只在编译期被使用,编译后就不再保留,因此程序运行时无法获取类的信息。这时就需要使用「运行期类型信息」,即 RTTI(Run-Time Type Information)。 参考 Qt中的元对象系统(Meta-Object System) Qt元对象系统:QMetaObject

2023-07-22 · 1 min · 24 words · RamLife