在编写代码时我们可以将调试信息打印至Qt的控制台查看,打包后交给硬件测试通信时为了方便他人查看指令添加一个调试窗口。
目录
1.输出至控制台
在pro文件中添加
CONFIG += console
效果如上。此方法会弹出一个cmd窗口打印调试信息。
优点:方便,只有一行代码;
缺点:无法实现动态开关,不适合程序发布使用
2.输出至控件和文件
使用 qInstallMessageHandler 自定义消息处理流程。
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static QTextEdit * debugEdit;
QTextEdit * MainWindow::debugEdit = nullptr;
定义静态的消息处理函数和静态的文本框控件指针并在类外初始化。
消息处理函数可参考Qt帮助文档:
void MainWindow::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// 加锁
static QMutex mutex;
mutex.lock();
if(type == QtDebugMsg){//界面显示
QString message = QString("%1 %2").arg(msg).arg("\r\n");
if(!debugEdit->isHidden()){
debugEdit->append(message);
}
}
QString text;
if(type == QtInfoMsg){
text = QString("Info:");
}
if(type == QtWarningMsg){
text = QString("Warning:");
}
if(type == QtCriticalMsg){
text = QString("Critical:");
}
if(type == QtFatalMsg){
text = QString("Fatal:");
}
// 设置输出信息格式
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString current_date = QString("(%1)").arg(current_date_time);
QString message = QString("%1 %2 %3 %4").arg(text).arg(" ").arg(msg).arg(current_date);
// 输出信息至文件中(读写、追加形式)
QFile file("log.txt");
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream << message << "\r\n";
file.flush();
file.close();
// 解锁
mutex.unlock();
}
我这里是将Debug信息输出到文本框里,其他类型的输出到文件。
qInstallMessageHandler(outputMessage);
debugEdit = new QTextEdit();
debugEdit->setWindowTitle("调试窗口");
debugEdit->resize(500,300);
//随主窗口一起关闭
debugEdit->setAttribute(Qt::WA_QuitOnClose,false);
debugEdit->hide();
在主界面构造函数中初始化调试窗口并隐藏,通过主界面的按钮点击弹出,这样即使在程序发布时也可以设置通过一系列操作后弹出调试窗口来查看指令。
3.新增:手动打开关闭控制台输出日志
点击按钮后弹出控制台窗口,绑定标准输出,设置标志位为真,重定向输出,使用标准输出打印调试信息,关闭时解绑,清空标志位,去掉重定向;在控制台 按下“Ctrl + c”和点击控制台窗口关闭按钮程序会退出,解决思路:给控制台窗口添加回调函数监测关闭事件进行处理,不在阐述,自行百度。
效果:
#include <Windows.h>
void Widget::on_pushButton_clicked()
{
QString text = ui->pushButton->text();
if("open console" == text){
AllocConsole();
SetConsoleTitleA("Debug output test");
FILE * file;
freopen_s(&file,"CONOUT$","w+t",stdout);
debugForConsole = true;
qInstallMessageHandler(messageHandler);
ui->pushButton->setText("close console");
}
else {
debugForConsole = false;
fclose(stdout);
FreeConsole();
qInstallMessageHandler(nullptr);
ui->pushButton->setText("open console");
}
}
void Widget::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// 加锁
static QMutex mutex;
mutex.lock();
QString msgtype;
if(type == QtDebugMsg){
msgtype = QString("Debug:");
}
if(type == QtInfoMsg){
msgtype = QString("Info:");
}
if(type == QtWarningMsg){
msgtype = QString("Warning:");
}
if(type == QtCriticalMsg){
msgtype = QString("Critical:");
}
if(type == QtFatalMsg){
msgtype = QString("Fatal:");
}
// 设置输出信息格式
QString datetime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString message = QString("%1 %2 %3 %4\n").arg(msgtype).arg(" ").arg(msg).arg(datetime);
if(debugForConsole){
std::cout<<message.toStdString();
mutex.unlock();
return;
}
mutex.unlock;
return;
}