QT LInux 开发中一些常用的方法
qDebug自定义打印
调用如下方法:
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))qInstallMsgHandler(customMessageHandler);
#elseqInstallMessageHandler(customMessageHandler);
#endif
回调方法如下:
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
void customMessageHandler(QtMsgType type, const char *str)
{//QString txt=str;//cout<<str.data();if(type<g_qtdebuglevel)return;fwrite(str,strlen(str),1,stdout);// fflush(stdout);if(type == QtFatalMsg){// 打印异常信息qCritical() << "Exception caught:" << str <<endl;// 获取堆栈信息void *stack[100];int size = backtrace(stack, 100);char **symbols = backtrace_symbols(stack, size);qDebug() << "Backtrace:";for (int i = 0; i < size; ++i) {qDebug() << symbols[i];}qDebug() << endl;free(symbols);// 退出程序if (type == QtFatalMsg)abort();}}#elsevoid customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString & str)
{//QString txt=str;//cout<<str.data();if(type<g_qtdebuglevel)return;fwrite(str.toUtf8(),str.toUtf8().length(),1,stdout);fflush(stdout);
}
#endifextern "C" {
int start_video(void);
int stop_video(void);
int AudioInit();
}int main_test(int argc, const char** argv);void load_pos_init(void)
{std::ifstream is;Json::Reader reader;is.open ("./pos_init.json", std::ios::binary);if(!reader.parse(is,json_init)){printf("load pos_init.json error \n");return;}is.close();if(json_init.isMember("runmode")){runmode = json_init["runmode"].asInt();}if(json_init.isMember("log_level")){log_level = json_init["log_level"].asInt();}if(json_init.isMember("waring_unupload_record")){waring_unupload_record = json_init["waring_unupload_record"].asInt();}if(json_init.isMember("waring_unupload_record_interval")){waring_unupload_record_interval = json_init["waring_unupload_record_interval"].asInt();}qDebug() << "json init:" << json_init.toStyledString().c_str() <<endl;//从 appver.txt文件里读取appVer的版本,然后写到 json_init里面,防止,json_init里面的版本不对的问题std::string filename = "./appver.txt"; // 你的文件名std::ifstream file(filename); // 尝试打开文件if (file.is_open()) { // 判断文件是否成功打开std::string line;if (std::getline(file, line)) { // 只读取一行std::cout << "appver 第一行内容: " << line << std::endl;json_init["AppVer"] = line;} else {std::cout << "appver 文件为空或读取失败" << std::endl;}file.close(); // 关闭文件} else {std::cout << "appver 文件不存在或无法打开" << std::endl;}}/*** @brief load_mqtt_config* MQTTT ip port 用户名,密码配置存储文件*/
void load_mqtt_config(void)
{std::ifstream is("./mqtt_config.json", std::ios::binary);if (!is.is_open()) {std::cerr << "Failed to open mqtt_config.json" << std::endl;return;}Json::Reader reader;if (!reader.parse(is, json_mqtt_config)) {std::cerr << "Failed to parse mqtt_config.json" << std::endl;is.close();return;}is.close();std::cout << "MQTT config loaded successfully." << std::endl;
}
打印段错误
有时程序运行过程中会报错,但是我们不知道报错原因,可以用这种方式捕获信号,然后就爱那个错误信息打印出来
// 安装信号处理函数signal(SIGSEGV, handleSignal); // 处理 SIGSEGV (segmentation fault) 信号signal(SIGABRT, handleSignal); // 处理 SIGABRT (abort) 信号signal(SIGILL, handleSignal); // 处理 SIGILL (illegal instruction) 信号signal(SIGFPE, handleSignal); // 处理 SIGFPE (floating point exception) 信号signal(SIGALRM, handleSigalrm); // 安装信号处理器
void handleSignal(int sig)
{void* array[10];size_t size;// 获取堆栈帧size = backtrace(array, 10);// 将堆栈帧转换为符号名称char** symbols = backtrace_symbols(array, size);// 打印堆栈跟踪信息qDebug() << "Caught signal:" << sig;for (size_t i = 0; i < size; i++) {qDebug() << symbols[i];}qDebug() << endl;// 解析符号名称以获取源文件和行号QString firstSymbol(symbols[0]);QRegExp regex("\\[(.*)\\]\\s*([^\\+]+)\\s*\\+\\s*(0x[0-9a-fA-F]+)");if (regex.exactMatch(firstSymbol)) {QString sourceFile = regex.cap(1);QString functionName = regex.cap(2);QString offset = regex.cap(3);qDebug() << "Error in" << sourceFile << "at" << functionName << "+" << offset << endl;}// 释放内存free(symbols);// 继续默认的信号处理signal(sig, SIG_DFL);raise(sig);
}
将日志输出到文件
日志输出到文件,我们可以运行交脚本的时候,将日志输出到指定的目录,例如:我们的成熟名是demo,那么脚本可以这样写:
#!/bin/sh
export LD_LIBRARY_PATH=/root/user/lib/lib_st:/root/user/lib:/root/user/qt_env/lib:/root/user/qt_env/gpnpsdk:/root/arm_libs/:$LD_LIBRARY_PATH
cd /root/# 指定日志目录路径
log_dir="/root/tfcard/log"# 创建日志目录(如果不存在)
mkdir -p "$log_dir"# 获取当前日期
current_date=$(date '+%Y-%m-%d')
echo $current_date# 生成日志文件名
log_file="$log_dir/log_$current_date.txt"
echo $log_file# 删除超过三天的日志文件
find "$log_dir" -name "log_*.txt" -type f -mtime +3 -deletewhile true
do
echo "demo START"
./demo -display "transformed:rot90:linuxfb:0" -qws -nomouse >> "$log_file"
sleep 5
done
上面的脚本我们会运行我们的程序,并且值打印3天的日志,超过3天则会删除多余的日志
显示图片
首先调用 QPixmap的load方法加载图片
m_pixmapBg1.load(":/res/jpg/bg-1.png");
然后在重写paintEvent方法,在改方法里调用
void MainWindow::drawBgup(QPainter *painter)
{QRect rect(0, 0, m_pixmapBg1.rect().width(), m_pixmapBg1.rect().height());if(bgpaint){//显示背景图片painter->drawPixmap(rect, m_pixmapBg1);}else{painter->setCompositionMode(QPainter::CompositionMode_Clear);painter->fillRect(rect,Qt::SolidPattern);}}
void MainWindow::paintEvent(QPaintEvent *) {QPainter painter(this);painter.save();drawBgup(&painter);painter.restore();}
子线程向主线程发送消息改变UI布局
主线程中创建子线程
this->worker = new pos_worker_thread(this);
将子线程和主线程通过信号和槽绑定起来
connect(worker,SIGNAL(error(const QString&)),this,SLOT(showError(const QString&)));
在子线程中 通过 emit error(“”)发送信号给主线程中绘制界面