- 編程的過程中經(jīng)常遇到需要將QString轉(zhuǎn)成char *或者const char *的情況,在轉(zhuǎn)換成QByteArray后調(diào)用.data()或者.constData()函數(shù)進(jìn)行轉(zhuǎn)換,這里需要注意的是,如果轉(zhuǎn)換類型是const char *盡管用data()不會出錯,會給你自動轉(zhuǎn)換,但是還是不建議,因為深拷貝了一份,理論上增加了內(nèi)存開銷,如果字符串長度小還好,一旦很長,這個開銷挺大,這是個好的編程習(xí)慣。
//查閱代碼得知data函數(shù)有兩個重載
inline char *QByteArray::data()
{ detach(); return d- >data(); }
inline const char *QByteArray::data() const
{ return d- >data(); }
inline const char *QByteArray::constData() const
{ return d- >data(); }
QByteArray data = "abc";
//深拷貝
char *d1 = data.data();
//深拷貝
const char *d2 = data.data();
//淺拷貝
const char *d3 = data.constData();
//深拷貝
test(data.data());
//淺拷貝
test(data.constData());
void test(const char *data)
{
}
//至于什么時候調(diào)用.data()會淺拷貝,酷碼大佬說是當(dāng)QByteArray被const修飾的時候
const QByteArray data;
//淺拷貝
const char *d = data.data();
//酷碼大佬補(bǔ)充:自Qt 5.7版本以來,引入了qAsConst函數(shù),專用于無腦轉(zhuǎn)換。
//這個函數(shù)實現(xiàn)了C++17標(biāo)準(zhǔn)中的std::as_const()函數(shù)的功能,將一個非常量的左值轉(zhuǎn)為常量的左值。
//增加qAsConst函數(shù)是為了Qt自己的非const 的容器能實現(xiàn)C++11標(biāo)準(zhǔn)的基于范圍的循環(huán)。
//該函數(shù)主要用于qt容器在隱式共享中不被detach。
QString s = "abc";
//下面會深拷貝引起性能損失
for (QChar ch : s)
//不會深拷貝
for (QChar ch : qAsConst(s))
//下面也是淺拷貝,但是在編程時、在現(xiàn)實中,聲明為const往往不容易做到。
const QString s;
for (QChar ch : s)
//總結(jié):對Qt自己實現(xiàn)的容器如:QVector、QMap、 QHash、QLinkedList、QList等,如果一定要用基于for(var : container)范圍的循環(huán),則請用如下形式:
for (var : qAsConst(container))
- 新版的Qt6.5在ubuntu上編譯運(yùn)行程序后會提示 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. ,無法正常彈出窗體程序,你需要主動安裝xcb的相關(guān)庫。sudo apt install libxcb*
- 有些場景下我們需要在 QApplication a(argc, argv); 前面執(zhí)行一些處理,比如 QApplication::setAttribute 就必須在最前面執(zhí)行,而很多時候這個設(shè)置的參數(shù)不能改寫死,畢竟現(xiàn)場的環(huán)境千差萬別,希望通過配置文件來配置,那么問題來了,讀取配置文件一般需要指定路徑才能正常讀取到,如果是 ./ 這種,很可能未必是應(yīng)用程序的當(dāng)前路徑,如果你是雙擊運(yùn)行的程序,那肯定是應(yīng)用程序的當(dāng)前路徑,不是雙擊運(yùn)行那就是系統(tǒng)環(huán)境中的當(dāng)前路徑,意味著你開機(jī)啟動或者用system、QProcess等方式在開機(jī)后調(diào)用啟動的話,就未必正確了。為了保證這個路徑的正確,必須從main函數(shù)的 argv 第一個值獲取,通過查閱Qt自身代碼中獲取路徑,也是從這個參數(shù)獲取。
//程序最前面獲取應(yīng)用程序路徑和名稱
static void getCurrentInfo(char *argv[], QString &path, QString &name);
//程序最前面讀取配置文件節(jié)點的值
static QString getIniValue(const QString &fileName, const QString &key);
static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString());
void QtHelper::getCurrentInfo(char *argv[], QString &path, QString &name)
{
//必須用fromLocal8Bit保證中文路徑正常
QString argv0 = QString::fromLocal8Bit(argv[0]);
QFileInfo file(argv0);
path = file.path();
name = file.baseName();
}
QString QtHelper::getIniValue(const QString &fileName, const QString &key)
{
QString value;
QFile file(fileName);
if (file.open(QFile::ReadOnly | QFile::Text)) {
while (!file.atEnd()) {
QString line = file.readLine();
if (line.startsWith(key)) {
line = line.replace("n", "");
line = line.trimmed();
value = line.split("=").last();
break;
}
}
}
return value;
}
QString QtHelper::getIniValue(char *argv[], const QString &key, const QString &dir)
{
QString path, name;
QtHelper::getCurrentInfo(argv, path, name);
QString fileName = QString("%1/%2%3.ini").arg(path).arg(dir).arg(name);
return getIniValue(fileName, key);
}
int main(int argc, char *argv[])
{
int openGLType = QtHelper::getIniValue(argv, "OpenGLType").toInt();
QtHelper::initOpenGL(openGLType);
QApplication a(argc, argv);
...
}
- 當(dāng)我們對QTableView/QTreeView/QTableWidget/QTreeWidget某行選中后,會發(fā)現(xiàn)某些單元格設(shè)置的前景色被覆蓋了,比如設(shè)置的紅色,一旦選中就變成了白色,這肯定不是我們想要的,需要用自定義委托將其去掉。
class ItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegate(QObject *parent = 0);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#include "itemdelegate.h"
ItemDelegate::ItemDelegate(QObject *parent) : QItemDelegate(parent)
{
}
void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem option2 = option;
QColor color = index.data(Qt::ForegroundRole).value< QColor >();
if (color.isValid() && color != option.palette.color(QPalette::WindowText)) {
option2.palette.setColor(QPalette::HighlightedText, color);
}
QItemDelegate::paint(painter, option2, index);
}
//對所有單元格設(shè)置該委托
ui- >tableWidget- >setItemDelegate(new ItemDelegate);
- 有些時候我們需要在項目文件比如pro/pri中識別當(dāng)前Qt套件是否存在某個模塊以及是否引入過某個模塊,存在則引入,同時也希望代碼中也能識別是否引入過某個模塊比如sql模塊,判斷后再進(jìn)行對應(yīng)的處理。
//項目文件中判斷
//如果當(dāng)前套件中有multimedia模塊則引入multimedia模塊
qtHaveModule(multimedia) {QT += multimedia}
//在項目文件中已經(jīng)通過 QT += multimedia 引入過模塊
contains(QT, multimedia) {}
//代碼文件判斷
#ifdef QT_MULTIMEDIA_LIB
qDebug() < < "multimedia module is enabled";
#else
qDebug() < < "multimedia module is not enabled";
#endif
- 對MDI窗體區(qū)域設(shè)置背景顏色透明,會發(fā)現(xiàn) QMdiArea{background:transparent;} 無效,哪怕是指定顏色 QMdiArea{background:#ff0000;} 或者 QMdiArea{background-color:#ff0000;} 都不行,這就很無語了,原來要用弱屬性機(jī)制才行。QMdiArea{qproperty-background:transparent;}
- 當(dāng)樣式中啟用了禁用樣式 *:disabled{xxx} 的時候,會發(fā)現(xiàn)MDI子窗體無法拉伸了,這應(yīng)該是Qt內(nèi)部的BUG,怎么解決呢,只需要重新設(shè)置MDI這個類別的禁用樣式的邊框樣式即可。QMdiSubWindow:disabled{border:8px solid rgba(0,0,0,0);}
- 用QProcess執(zhí)行命令或者啟動可執(zhí)行文件,默認(rèn)寫法不支持帶空格的路徑,比如 Program Files ,需要在這個路徑前后加上雙引號才行,估計可能內(nèi)部會用空格分割字符串導(dǎo)致解析失敗。普通路徑加上引號也能正常執(zhí)行,所以為了確保以防萬一,統(tǒng)一加上引號即可。
QString cmd = "c:/Program Files/a.exe";
//下面這個會執(zhí)行失敗
QProcess::startDetached(cmd);
//前后加上引號就可以正常執(zhí)行
cmd = """ + cmd + """;
QProcess::startDetached(cmd);
- 在循環(huán)中取值,臨時變量的定義盡量在循環(huán)外層定義,每次在循環(huán)里層定義會增加開銷,特別是復(fù)雜類型比如QString(基礎(chǔ)類型比如int/bool差別不大),循環(huán)次數(shù)越多,性能差別越大。
void MainWindow::on_pushButton_clicked()
{
QElapsedTimer timer;
timer.start();
QString s;
QString text = "abc";
for (int i = 0; i < 10000; ++i) {
s = text.at(0);
}
qDebug() < < "方式1" < < timer.nsecsElapsed();
}
void MainWindow::on_pushButton_2_clicked()
{
QElapsedTimer timer;
timer.start();
QString text = "abc";
for (int i = 0; i < 10000; ++i) {
QString s = text.at(0);
}
qDebug() < < "方式2" < < timer.nsecsElapsed();
}
//debug模式下方式1比方式2快6倍+
//release模式下方式1比方式2快30倍+
- Qt的屬性機(jī)制非常強(qiáng)大,除了可以用來控制樣式表,也可以很方便的用來傳值,比如qml中的值傳遞,有時候我們寫了一個通用類,希望這個類可以做很多事情,但是又希望其中有一些特殊變量存取值,一種辦法是直接定義私有變量,提供get/set接口函數(shù),還有一種偷懶的辦法就是用屬性setProperty/property,然Qt內(nèi)部從元對象數(shù)據(jù)層面自己管理,這樣不用在類中寫對應(yīng)的變量和get/set函數(shù)。但是肯定有性能損耗,性能上肯定比變量低,所以要看具體的實際需求,如果不是非常頻繁的調(diào)用setProperty/property,通用性優(yōu)先的話,那用屬性機(jī)制會更方便。個人推薦方式三,繼承通用類,在子類中增加set/get。
void MainWindow::on_pushButton_clicked()
{
QElapsedTimer timer;
timer.start();
for (int i = 0; i < 10000; ++i) {
Test *t = new Test;
//t- >setId(i);
//t- >setName("test");
t- >getName();
}
qDebug() < < "方式1" < < timer.nsecsElapsed();
}
void MainWindow::on_pushButton_2_clicked()
{
QElapsedTimer timer;
timer.start();
for (int i = 0; i < 10000; ++i) {
Test *t = new Test;
//t- >setProperty("id", i);
//t- >setProperty("name", "test");
t- >property("name").toString();
}
qDebug() < < "方式2" < < timer.nsecsElapsed();
}
//對比測試和具體的變量類型無關(guān)/int和QString類型產(chǎn)生的性能差別一樣
//setProperty比setxxx方式性能差3倍+
//property比getxxx方式性能差1.3倍
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
2976瀏覽量
73815 -
編程
+關(guān)注
關(guān)注
88文章
3565瀏覽量
93536 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4284瀏覽量
62325 -
char
+關(guān)注
關(guān)注
0文章
11瀏覽量
3700
發(fā)布評論請先 登錄
相關(guān)推薦
如何將orcad轉(zhuǎn)成mentor_expedition
使用Orcad畫電路圖后,將每一個零件的PCB Footprint填入,格式如下圖所示
發(fā)表于 06-24 17:22
?2880次閱讀
windows下QT編程中_TCHAR與QString之間的轉(zhuǎn)換
;utf16()#define TCHARToQString(x)QString::fromUtf16((x))#define TCHARToQStringN(x,y)QString::fromUtf16
發(fā)表于 03-21 11:22
如何將PowerPCB轉(zhuǎn)成Protel的詳細(xì)過程和軟件
如何將PowerPCB轉(zhuǎn)成Protel的詳細(xì)過程第一步:用PowerPCB打開文件,選擇“File”---“Export”導(dǎo)出,如圖:導(dǎo)出格式Format選擇PowerPCBV3.5的,然后
發(fā)表于 11-24 16:25
如何將char型指針強(qiáng)制轉(zhuǎn)換成UCHAR型指針
如何將char型指針強(qiáng)制轉(zhuǎn)換成UCHAR型指針??????、、
發(fā)表于 12-21 15:51
如何將ASCII碼轉(zhuǎn)成16進(jìn)制數(shù)?
如ASCII碼“”3133”,轉(zhuǎn)成16進(jìn)制數(shù)應(yīng)該是0x13,請問VHDL語言怎么寫呢?
發(fā)表于 05-16 18:51
如何將PDF轉(zhuǎn)成CAD
`現(xiàn)在很多設(shè)計圖紙等操作者都需要對PDF格式得圖紙進(jìn)行二次編輯,但是PDF文件又不能直接進(jìn)行編輯修改,那我們該如何操作呢,我們可以將PDF轉(zhuǎn)成CAD文件然后再進(jìn)行轉(zhuǎn)換得操作,接下來就讓小編來具體介紹
發(fā)表于 07-03 18:17
如何將一個INT型數(shù)據(jù)轉(zhuǎn)換成2個CHAR型數(shù)據(jù)?
如何將一個INT型數(shù)據(jù)轉(zhuǎn)換成2個CHAR型數(shù)據(jù)?
發(fā)表于 11-03 06:20
如何將Cadence的原理圖和PCB轉(zhuǎn)成PADS資料下載
電子發(fā)燒友網(wǎng)為你提供如何將Cadence的原理圖和PCB轉(zhuǎn)成PADS資料下載的電子資料下載,更有其他相關(guān)的電路圖、源代碼、課件教程、中文資料、英文資料、參考設(shè)計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
發(fā)表于 04-19 08:54
?46次下載
數(shù)控直流穩(wěn)壓電源如何將交流電壓轉(zhuǎn)成直流電壓?
數(shù)控直流穩(wěn)壓電源如何將交流電壓轉(zhuǎn)成直流電壓? 數(shù)控直流穩(wěn)壓電源是一種將交流電壓轉(zhuǎn)換為直流電壓的裝置。在現(xiàn)代電子設(shè)備中,直流電壓廣泛應(yīng)用,因為它在穩(wěn)定性、可調(diào)性和可靠性方面具有優(yōu)勢。為了滿足設(shè)備的要求
評論