qt編譯帶debug信息
A. QT 自定義處理調試信息
在QT中,我們經常使用 qDebug() 、 qInfo() 等來列印調試的信息,但是當列印信息過多時,很不利於查找閱讀。所以本文介紹使用 QtMessageHandler 類中的 qInstallMessageHandler() 來自定義處理調試信息。
一、在主線程中注冊調試信息處理回調
這里的 outputMessage 即為自定義的觸發函數,當程序有調試信息時,將會調用此函數
二、實現觸發函數
說明:此函數需要接受三個參數
QtMsgType type :表示調試信息類型,包括 QtDebugMsg (調試消息)、 QtInfoMsg (信息消息)、 QtWarningMsg (警告消息和可恢復的錯誤)、 QtCriticalMsg (關鍵錯誤和系統錯誤)、 QtFatalMsg (致命錯誤)
const QMessageLogContext &context :表示有關日誌消息的其他信息,比如文件名 context.file 、行號 context.line 等等。
const QString &msg :表示原始的調試信息。
這樣,我們就可以根據調試信息類型,自定義處理調試信息,並列印到日誌文件等等。
但是有時候,我們會有這樣的需求,有些類型如神的信息需要列印到屏幕,而有些類型的信息需要列印渣頃虧到日誌。當注冊了調試信息處理的回調,如何分類去處理呢?
查看QT文檔中對於 qInstallMessageHandler() 的描述,可以知道該函數返回一個指向上一個消息處理程序,可以理解為上一個消息處理函數的指針。因此在使用 qInstallMessageHandler() 注冊回調時,可以保存函數的返回,從而用之前的處理程序來處理調試信息
例如:
使用 s_messageHandler 來保存函數的返回值,即指向了上一個消息處理函數。在 outputMessage() 函數中使用 s_messageHandler
這樣就實現了將Info等信息列印到日誌,而debug信息列印到屏幕。
註: 以上寫入日乎亂志文件的寫法,並不是線程安全的,需要加鎖來保證線程安全,這里就不再贅述。
正常的運行程序,日誌內容如下:
實際項目中遇到了編譯出的Release版本,日誌輸出沒有文件信息、行數的問題。如下:
解決方法:
在.pro文件中添加宏
一定要先刪除掉之前編譯的中間文件,重新qmake!這樣就可以在Release版本中正確輸出日誌信息。
B. 為什麼我用Qt5.6編譯出的debug與release程序在不同的目
這個十分簡單, 如果我理解的沒有錯的話, 你應該是在新建項目時沒有添加Release對象吧?
1. 點擊左側邊欄的Projects
2. 在Build Step里的qmake build configuration中選擇Release
此時你編譯出來的對象就是release的了...
如果是要上交的內容, 更改下build directory, 就OK了
如果你是在Shell下的話... qmake加參數 "-CONFIG+=Release(或者Debug)"
C. qt4.8.5build debug libraries 編譯有什麼用
QT Debug大集合 詳細講解是本文要介紹的內容,相信友們應該在編程過程中遇到各種各樣的Debug,先來看內容。QT Debug集錦~ 這篇是在10年測試QT 過程中遇到的問題:
1、中文顯示問題:
#include <QApplication> #include <QLabel> #include <QTextCodec> int main(int argc, char* argv[]) { QApplication app(argc,argv); QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); QLabel *label = new QLabel(tr("這里是中文")); label->Show(); return app.exec(); }
編譯代碼,得到的錯誤是: 'tr'在此作用域中尚未聲明。
昨天為什麼沒有出現這種錯誤呢?因為昨天的代碼是從qt creator生成的MainWindow中挑出來的,tr被聲明為QObject的一個static方法,因此在MainWindow中使用tr不會有問題。
把上面的QLabel *label=new QLabel(tr("這里是中文"));
改為
QLabel *label=new QLabel(QObject::tr("這里是中文"));
2、中文問題:
使用sqlite資料庫顯示亂碼的問題
本人近日在使用QT進行sqlite資料庫編程時,出現中文數據顯示亂碼情況,附源碼如下:
//main.cpp #include <QtGui> #include <QtCore/QTextCodec> #include <QSqlTableModel> #include <QTableView> #include <QHeaderView> #include <QSqlRecord> #include <QtGui/QLabel> #include <QString> #include <QVariant> #include "connection.h" #include "sql.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK")); //創建資料庫連接 if (!createConnection()) return 1; //創建學生信息表 createTables(); //初始添加數據 addData(); enum{ Student_Id = 0, Student_Schnum = 1, Student_Name = 2, Student_Sex = 3, Student_Nation = 4 }; QSqlTableModel *model = new QSqlTableModel(); model->setTable("student"); model->setSort(Student_Schnum, Qt::AscendingOrder); model->setHeaderData(Student_Schnum, Qt::Horizontal, QObject::tr("學號")); model->setHeaderData(Student_Name, Qt::Horizontal, QObject::tr("姓名")); model->setHeaderData(Student_Sex, Qt::Horizontal, QObject::tr("性別")); model->setHeaderData(Student_Nation, Qt::Horizontal, QObject::tr("民族")); model->select(); QTableView *view = new QTableView; view->setModel(model); view->setSelectionMode(QAbstractItemView::SingleSelection); view->setSelectionBehavior(QAbstractItemView::SelectRows); view->setColumnHidden(Student_Id, true); view->resizeColumnsToContents(); view->setEditTriggers(QAbstractItemView::NoEditTriggers); QHeaderView *header = view->horizontalHeader(); header->setStretchLastSection(true); view->show(); return a.exec(); } //connection.h #ifndef CONNECTION_H #define CONNECTION_H #include <QMessageBox> #include <QSqlDatabase> #include <QSqlError> #include <QSqlDriver> inline bool createConnection() { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("sim.dat"); if (!db.open()) { QMessageBox::warning(0, QObject::tr("Database Error"), db.lastError().text()); return false; } return true; } #endif // CONNECTION_H //sql.h #include <QSqlQuery> #ifndef SQL_H #define SQL_H inline void createTables() { QSqlQuery query; query.exec("CREATE TABLE student (" "id INTEGER PRIMARY KEY, " "schnum INTEGER NOT NULL, " "name VARCHAR(40) NOT NULL, " "sex VARCHAR(4) NOT NULL, " "nation VARCHAR(10) NOT NULL)"); } inline void addData(){ QSqlQuery query; for(int i =0;i<100;i++){ query.exec("INSERT INTO student (schnum, name, sex, nation) VALUES (2614103, '天殘腳,'男', '漢族')"); } } #endif // SQL_H
上網查了許多無果,後來在閱讀一篇技術文章中無意發現,原來在插入數據語句若有中文必須先QObject::tr()一番,即進行編碼,
將 Sql.h 中 query.exec("INSERT INTO student (schnum, name, sex, nation) VALUES (2614103, '天殘腳,'男', '漢族')"); 改為如下 query.exec(QObject::tr("INSERT INTO student (schnum, name, sex, nation) VALUES (2614103, '天殘腳,'男', '漢族')"));
結果在顯示中都能得正確顯示。
注意,如果語句 QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));中的編碼改為utf-8則會顯示亂碼。
3、中文問題:
如果使程序只支持一種編碼,也可以直接把整個應用程序的編碼設置為GBK編碼, 然後在字元串之前 加
tr(QObject::tr), qApp->setDefaultCodec( QTextCodec::codecForName("GBK") ); QLabel *label = new QLabel( tr("中文標簽") );
4、找不到<QtSql >
求助:提示無法打開包含文件QtSql
.Pro文件里加入 QT += sql
4、No rule to make target 'mkspecs/default/qmake.conf', needed by `Makefile'. Stop. 錯誤
mingw32-make: *** No rule to make target `http://www.cnblogs.com/http://www.cnblogs.com/Qt/4.3.3/mkspecs/default/qmake.conf', needed by `makefile'. Stop. make[2]: Entering directory `/home/lzy/tps2/rplan/super' make[2]: *** No rule to make target `/home/lzy/qt/qt-3.3.2/mkspecs/default/qmake.conf', needed by `Makefile'. Stop. make[2]: Leaving directory `/home/lzy/tps2/rplan/super'
5、mingw32\bin\ld.exe: cannot find -lqtmaind錯誤
這個錯誤是缺少某些庫,將mingw重新下載安裝即可。
6、編譯時可能會遇到如下錯誤:previous declaration 'long int InterlockedIncrement(long int*)' here
此為qt的bug需要修改源代碼 (Qt\4.4.3\src\corelib\arch\qatomic_windows.h),原文件如下:
Solution:
(1) Qt\4.4.3\src\corelib\arch\qatomic_windows.h:
#if !(defined Q_CC_BOR) || (__BORLANDC__ < 0x560) extern "C" { __declspec(dllimport) long __stdcall InterlockedCompareExchange(long *, long, long); __declspec(dllimport) long __stdcall InterlockedIncrement(long *); __declspec(dllimport) long __stdcall InterlockedDecrement(long *); __declspec(dllimport) long __stdcall InterlockedExchange(long *, long); __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long *, long); } #else extern "C" { __declspec(dllimport) long __stdcall InterlockedCompareExchange(long volatile*, long, long); __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile*); __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile*); __declspec(dllimport) long __stdcall InterlockedExchange(long volatile*, long); __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long volatile*, long); } #endif you will see above code in Qt\4.4.3\src\corelib\arch\qatomic_windows.h: file. I modified like below and it works. /*#if !(defined Q_CC_BOR) || (__BORLANDC__ < 0x560) extern "C" { __declspec(dllimport) long __stdcall InterlockedCompareExchange(long *, long, long); __declspec(dllimport) long __stdcall InterlockedIncrement(long *); __declspec(dllimport) long __stdcall InterlockedDecrement(long *); __declspec(dllimport) long __stdcall InterlockedExchange(long *, long); __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long *, long); } #else */ extern "C" { __declspec(dllimport) long __stdcall InterlockedCompareExchange(long volatile*, long, long); __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile*); __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile*); __declspec(dllimport) long __stdcall InterlockedExchange(long volatile*, long); __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long volatile*, long); } // #endif
7、編譯錯誤,顯示 can not find -lqtmaind。
這是qt的debug庫,安裝完成後需要再自己編譯這個庫。在Qt的開始菜單中,你可以找到一個程序 Qt 4.4.0 (Build Debug Libraries),運行這個程序就能編譯Qt的Debug庫了。
小結:QT debug大集合 詳細講解的內容介紹完了,希望本文對你有搜幫助。
D. qt如何把debug編譯成release版本
這個十分簡單, 如果我理解的沒有錯的話, 你應該是在新建項目時沒有添加Release對象吧?
1. 點擊左側邊欄的Projects
2. 在Build Step里的qmake build configuration中選擇Release
此時你編譯出來的對象就是release的了...
如果是要上交的內容, 更改下build directory, 就OK了
如果你是在Shell下的話... qmake加參數 "-CONFIG+=Release(或者Debug)"