天天看點

Qt開發經驗小技巧276-280

作者:Qt自定義控件

276. 對MDI窗體區域設定背景顔色透明,會發現 QMdiArea{background:transparent;} 無效,哪怕是指定顔色 QMdiArea{background:#ff0000;} 或者 QMdiArea{background-color:#ff0000;} 都不行,這就很無語了,原來要用弱屬性機制才行。QMdiArea{qproperty-background:transparent;}

277. 當樣式中啟用了禁用樣式 *:disabled{xxx} 的時候,會發現MDI子窗體無法拉伸了,這應該是Qt内部的BUG,怎麼解決呢,隻需要重新設定MDI這個類别的禁用樣式的邊框樣式即可。QMdiSubWindow:disabled{border:8px solid rgba(0,0,0,0);}

278. 用QProcess執行指令或者啟動可執行檔案,預設寫法不支援帶空格的路徑,比如 Program Files ,需要在這個路徑前後加上雙引号才行,估計可能内部會用空格分割字元串導緻解析失敗。普通路徑加上引号也能正常執行,是以為了確定以防萬一,統一加上引号即可。

```cpp

QString cmd = "c:/Program Files/a.exe";

//下面這個會執行失敗

QProcess::startDetached(cmd);

//前後加上引号就可以正常執行

cmd = "\"" + cmd + "\"";

QProcess::startDetached(cmd);

```

279. 在循環中取值,臨時變量的定義盡量在循環外層定義,每次在循環裡層定義會增加開銷,特别是複雜類型比如QString(基礎類型比如int/bool差别不大),循環次數越多,性能差别越大。

```cpp

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倍+

```

280. Qt的屬性機制非常強大,除了可以用來控制樣式表,也可以很友善的用來傳值,比如qml中的值傳遞,有時候我們寫了一個通用類,希望這個類可以做很多事情,但是又希望其中有一些特殊變量存取值,一種辦法是直接定義私有變量,提供get/set接口函數,還有一種偷懶的辦法就是用屬性setProperty/property,然Qt内部從元對象資料層面自己管理,這樣不用在類中寫對應的變量和get/set函數。但是肯定有性能損耗,性能上肯定比變量低,是以要看具體的實際需求,如果不是非常頻繁的調用setProperty/property,通用性優先的話,那用屬性機制會更友善。個人推薦方式三,繼承通用類,在子類中增加set/get。

```cpp

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();

}

//對比測試和具體的變量類型無關/int和QString類型産生的性能差别一樣

//setProperty比setxxx方式性能差3倍+

//property比getxxx方式性能差1.3倍

```

國内站點:[https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)

國際站點:[https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)

繼續閱讀