文章插圖

文章插圖
181. Qt天生就是linux的 , 從linux開始發展起來的 , 所以不少Qt程序員經常的開發環境是linux , 比如常用的ubuntu等系統 , 整理了一點常用的linux命令 。
| 命令 | 功能 |
| :—— | :—— |
| sudo -s | 切換到管理員 , 如果是 sudo -i 切換后會改變當前目錄 。|
| apt install g++ | 安裝軟件包(要管理員權限) , 另一個派系的是 yum install |
| cd /home | 進入home目錄 |
| ls | 羅列當前所在目錄所有目錄和文件 |
| ifconfig | 查看網卡信息包括IP地址 , windows上是 ipconfig 。|
| tar -zxvf bin.tar.gz | 解壓文件到當前目錄 |
| tar -jxvf bin.tar.xz | 解壓文件到當前目錄 |
| tar -zxvf bin.tar.gz -C /home | 解壓文件到/home目錄 , 記住是大寫的C 。|
| tar -zcvf bin.tar.gz bin | 將bin目錄壓縮成tar.gz格式文件(壓縮比一般) |
| tar -jcvf bin.tar.xz bin | 將bin目錄壓縮成tar.xz格式文件(壓縮比高 , 推薦) |
| tar -… | j z 表示不同的壓縮方法 , x表示解壓 , c表示壓縮 。|
| gedit 1.txt | 用記事本打開文本文件 |
| vim 1.txt | 用vim打開文件 , 很多時候可以縮寫用vi 。|
| ./configure make -j4 make install | 通用編譯源碼命令 , 第一步./configure執行配置腳本 , 第二步make -j4啟用多線程編譯 , 第三步make install安裝編譯好的文件 。|
| ./configure -prefix /home/liu/Qt-5.9.3-static -static -sql-sqlite -qt-zlib -qt-xcb -qt-libpng -qt-libjpeg -fontconfig -system-freetype -iconv -nomake tests -nomake examples -skip qt3d -skip qtdoc | Qt通用編譯命令 |
| ./configure -prefix /home/liu/Qt-5.9.3-static -static -release -nomake examples -nomake tests -skip qt3d | 精簡編譯命令 |
| ./configure –prefix=host –enable-static –disable-shared –disable-doc | ffmpeg編譯命令 |
182. Qt自帶的日志重定向機制非常簡單好用 , 自從用了以后再也不用什么斷點調試啥的了 , 在需要的地方支持qdebug輸出對應的信息 , 而且發布程序以后也可以開啟調試日志將其輸出查看等 。
“`cpp
//Qt5開始提供了日志上下文信息輸出 , 比如輸出當前打印消息所在的代碼文件、行號、函數名等 。
//如果是release還需要在pro中加上 DEFINES += QT_MESSAGELOGCONTEXT 才能輸出上下文 , 默認release關閉的 。
//切記不要在日志鉤子函數中再寫qdebug之類的 , 那樣就死循環了 。
//日志重定向一般就三種處理
//1: 輸出到日志文件比如txt文本文件 。
//2: 存儲到數據庫 , 可以分類存儲 , 以便相關人員查詢分析 。
//3: 重定向到網絡 , 對方用小工具連接程序后 , 所有打印信息通過tcp發過去 。
//日志重定向
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
void Log(QtMsgType type, const QMessageLogContext &context, const QString &msg)
#else
void Log(QtMsgType type, const char *msg)
#endif
{
//加鎖,防止多線程中qdebug太頻繁導致崩潰
static QMutex mutex;
QMutexLocker locker(&mutex);
QString content;
//這里可以根據不同的類型加上不同的頭部用于區分
switch (type) {
case QtDebugMsg:
content = QString(“%1”).arg(msg);
break;
case QtWarningMsg:
content = QString(“%1”).arg(msg);
break;
case QtCriticalMsg:
content = QString(“%1”).arg(msg);
break;
case QtFatalMsg:
【使用qt開發的軟件有哪些 用qt開發的大型軟件】content = QString(“%1”).arg(msg);
break;
}
//加上打印代碼所在代碼文件、行號、函數名
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
if (SaveLog::Instance()->getUseContext()) {
int line = context.line;
QString file = context.file;
QString function = context.function;
if (line > 0) {
content = QString(“行號: %1 文件: %2 函數: %3\n%4”).arg(line).arg(file).arg(function).arg(content);
}
}
#endif
//將內容傳給函數進行處理
SaveLog::Instance()->save(content);
}
//安裝日志鉤子,輸出調試信息到文件,便于調試
void SaveLog::start()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
qInstallMessageHandler(Log);
#else
qInstallMsgHandler(Log);
#endif
}
//卸載日志鉤子
void SaveLog::stop()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
qInstallMessageHandler(0);
#else
qInstallMsgHandler(0);
#endif
}
“`
183. 自從c++11標準以后 , 各種語法糖層出不窮 , 其中lambda表達式用的最廣 , 基本上從Qt5以后就支持lambda表達式 。對于習慣了c99的老一輩的程序員來說 , 這玩意是個新鮮事物 , 這里特意做個小理解筆記 。
– 代碼格式:[capture](parameters) mutable ->return-type {statement}
– [capture]:捕捉列表 , 捕捉列表總是出現在Lambda函數的開始處 , 實際上 , []是Lambda引出符 , 編譯器根據該引出符判斷接下來的代碼是否是Lambda函數 , 捕捉列表能夠捕捉上下文中的變量以供Lambda函數使用 。
– (parameters):參數列表 , 與普通函數的參數列表一致 , 如果不需要參數傳遞 , 則可以連同括號 () 一起省略 。
– mutable:mutable修飾符 , 默認情況下 , Lambda函數總是一個const函數 , mutable可以取消其常量性 。在使用該修飾符時 , 參數列表不可省略(即使參數為空) 。
– ->return-type:返回類型 , 用追蹤返回類型形式聲明函數的返回類型 , 我們可以在不需要返回值的時候也可以連同符號 -> 一起省略 。此外 , 在返回類型明確的情況下 , 也可以省略該部分 , 讓編譯器對返回類型進行推導 。
– {statement}:函數體 , 內容與普通函數一樣 , 不過除了可以使用參數之外 , 還可以使用所有捕獲的變量 。
捕捉列表有以下幾種形式:
– [var]表示值傳遞方式捕捉變量var 。
– [=]表示值傳遞方式捕捉所有父作用域的變量(包括this) 。
– [&var]表示引用傳遞捕捉變量var 。
– [&]表示引用傳遞方式捕捉所有父作用域的變量(包括this) 。
– [this]表示值傳遞方式捕捉當前的this指針 。
“`cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//按鈕單擊不帶參數
connect(ui->pushButton, &QPushButton::clicked, [] {
qDebug() << “hello lambda”;
});
//按鈕單擊帶參數
connect(ui->pushButton, &QPushButton::clicked, [] (bool isCheck) {
qDebug() << “hello lambda” << isCheck;
});
//自定義信號帶參數
connect(this, &MainWindow::sig_test, [] (int i, int j) {
qDebug() << “hello lambda” << i << j;
});
emit sig_test(5, 8);
}
“`
184. 由于Qt版本眾多 , 有時候為了兼容多個版本甚至跨度Qt4/Qt5/Qt6的兼容 , 有些頭文件或者類名等變了或者新增了 , 需要用到Qt版本的判斷 。需要注意的是如果在頭文件中使用 QT_VERSION_CHECK 需要先引入#include “qglobal.h”不然編譯失敗 , 因為 QT_VERSION_CHECK 這個函數在 qglobal.h 頭文件中 。
“`cpp
//至少要包含 qglobal.h , 理論上Qt所有的類都包含了這個頭文件 , 所以你引入Qt的其他頭文件也行比如 qobject.h
#include “qglobal.h”
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include “qscreen.h”
#else
#include “qdesktopwidget.h”
#endif
“`
185. 在使用QString轉換到char *或者const char *的時候 , 務必記得分兩步來完成 , 血的教訓 , 在一個場景中 , 就因為沒有分兩步走 , 現象是msvc的debug異常release正常 , mingw和gcc的debug和release都正常 , 這就很無語了 , 找問題找半天 , 對比法排除法按道理要么都有問題才對 。
– 轉換前QString的內容無關中文還是英文 , 要出問題都一樣 。
– 轉換中QByteArray無關具體類型 , toUtf8、toLatin1、toLocal8Bit等方法 , 要出問題都一樣 。
– 轉換后無關char *還是const char * , 要出問題都一樣 。
– 出問題的隨機性的 , 概率出現 , 理論上debug的概率更大 。
– 根據酷碼大佬分析可能的原因(不確定)是msvc為了方便調試 , debug會在內存釋放后做填充 , release則不會 。
“`cpp
QString text = “xxxxx”;
//下面這樣轉換很可能會有問題
char *data = http://www.mnbkw.com/jxjc/168654/text.toUtf8().data();
//分兩步轉換肯定不會有問題
QByteArray buffer = text.toUtf8();
char *data = http://www.mnbkw.com/jxjc/168654/buffer.data();
const char *data = http://www.mnbkw.com/jxjc/168654/buffer.constData();
- 田七粉泡開水喝的功效
- 免費的電子書閱讀器下載 txt電子書閱讀器免費下載
- 枸杞和紅棗泡水方法是什么
- 怎么蒸紅薯
- 蝦肉炒什么
- ?把女人比做車的污句子,老司機又要發車了
- excel的最新版本是多少 最新版excel是哪個版本
- 夸土很好怎么說,撩妹土味情話就要找些特殊的
- 逗女生開心的幽默套路對話,想要更加接近喜歡的女生嗎
- P圖的工具 P圖工具下載
