qDebug自定义打印
调用如下方法:
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
qInstallMsgHandler(customMessageHandler);
#else
qInstallMessageHandler(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();
}
}
#else
void 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);
}
#endif
extern "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 -delete
while 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(“”)发送信号给主线程中绘制界面