data (); } inline const char *QByt" />
0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何將QString轉(zhuǎn)成char

科技綠洲 ? 來(lái)源:網(wǎng)絡(luò)整理 ? 作者:網(wǎng)絡(luò)整理 ? 2023-11-24 15:33 ? 次閱讀
  1. 編程的過(guò)程中經(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()不會(huì)出錯(cuò),會(huì)給你自動(dòng)轉(zhuǎn)換,但是還是不建議,因?yàn)樯羁截惲艘环?,理論上增加了?nèi)存開(kāi)銷(xiāo),如果字符串長(zhǎng)度小還好,一旦很長(zhǎng),這個(gè)開(kāi)銷(xiāo)挺大,這是個(gè)好的編程習(xí)慣。
//查閱代碼得知data函數(shù)有兩個(gè)重載
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)
{    
}

//至于什么時(shí)候調(diào)用.data()會(huì)淺拷貝,酷碼大佬說(shuō)是當(dāng)QByteArray被const修飾的時(shí)候
const QByteArray data;
//淺拷貝
const char *d = data.data();

//酷碼大佬補(bǔ)充:自Qt 5.7版本以來(lái),引入了qAsConst函數(shù),專用于無(wú)腦轉(zhuǎn)換。
//這個(gè)函數(shù)實(shí)現(xiàn)了C++17標(biāo)準(zhǔn)中的std::as_const()函數(shù)的功能,將一個(gè)非常量的左值轉(zhuǎn)為常量的左值。
//增加qAsConst函數(shù)是為了Qt自己的非const 的容器能實(shí)現(xiàn)C++11標(biāo)準(zhǔn)的基于范圍的循環(huán)。
//該函數(shù)主要用于qt容器在隱式共享中不被detach。
QString s = "abc";
//下面會(huì)深拷貝引起性能損失
for (QChar ch : s)
//不會(huì)深拷貝
for (QChar ch : qAsConst(s))
//下面也是淺拷貝,但是在編程時(shí)、在現(xiàn)實(shí)中,聲明為const往往不容易做到。
const QString s;
for (QChar ch : s)

//總結(jié):對(duì)Qt自己實(shí)現(xiàn)的容器如:QVector、QMap、 QHash、QLinkedList、QList等,如果一定要用基于for(var : container)范圍的循環(huán),則請(qǐng)用如下形式:
for (var : qAsConst(container))
  1. 新版的Qt6.5在ubuntu上編譯運(yùn)行程序后會(huì)提示 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. ,無(wú)法正常彈出窗體程序,你需要主動(dòng)安裝xcb的相關(guān)庫(kù)。sudo apt install libxcb*
  2. 有些場(chǎng)景下我們需要在 QApplication a(argc, argv); 前面執(zhí)行一些處理,比如 QApplication::setAttribute 就必須在最前面執(zhí)行,而很多時(shí)候這個(gè)設(shè)置的參數(shù)不能改寫(xiě)死,畢竟現(xiàn)場(chǎng)的環(huán)境千差萬(wàn)別,希望通過(guò)配置文件來(lái)配置,那么問(wèn)題來(lái)了,讀取配置文件一般需要指定路徑才能正常讀取到,如果是 ./ 這種,很可能未必是應(yīng)用程序的當(dāng)前路徑,如果你是雙擊運(yùn)行的程序,那肯定是應(yīng)用程序的當(dāng)前路徑,不是雙擊運(yùn)行那就是系統(tǒng)環(huán)境中的當(dāng)前路徑,意味著你開(kāi)機(jī)啟動(dòng)或者用system、QProcess等方式在開(kāi)機(jī)后調(diào)用啟動(dòng)的話,就未必正確了。為了保證這個(gè)路徑的正確,必須從main函數(shù)的 argv 第一個(gè)值獲取,通過(guò)查閱Qt自身代碼中獲取路徑,也是從這個(gè)參數(shù)獲取。
//程序最前面獲取應(yīng)用程序路徑和名稱
static void getCurrentInfo(char *argv[], QString &path, QString &name);
//程序最前面讀取配置文件節(jié)點(diǎn)的值
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);
    ...
}
  1. 當(dāng)我們對(duì)QTableView/QTreeView/QTableWidget/QTreeWidget某行選中后,會(huì)發(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);
}

//對(duì)所有單元格設(shè)置該委托
ui- >tableWidget- >setItemDelegate(new ItemDelegate);
  1. 有些時(shí)候我們需要在項(xiàng)目文件比如pro/pri中識(shí)別當(dāng)前Qt套件是否存在某個(gè)模塊以及是否引入過(guò)某個(gè)模塊,存在則引入,同時(shí)也希望代碼中也能識(shí)別是否引入過(guò)某個(gè)模塊比如sql模塊,判斷后再進(jìn)行對(duì)應(yīng)的處理。
//項(xiàng)目文件中判斷
//如果當(dāng)前套件中有multimedia模塊則引入multimedia模塊
qtHaveModule(multimedia) {QT += multimedia}
//在項(xiàng)目文件中已經(jīng)通過(guò) QT += multimedia 引入過(guò)模塊
contains(QT, multimedia) {}

//代碼文件判斷
#ifdef QT_MULTIMEDIA_LIB
    qDebug() < < "multimedia module is enabled";
#else
    qDebug() < < "multimedia module is not enabled";
#endif
  1. 對(duì)MDI窗體區(qū)域設(shè)置背景顏色透明,會(huì)發(fā)現(xiàn) QMdiArea{background:transparent;} 無(wú)效,哪怕是指定顏色 QMdiArea{background:#ff0000;} 或者 QMdiArea{background-color:#ff0000;} 都不行,這就很無(wú)語(yǔ)了,原來(lái)要用弱屬性機(jī)制才行。QMdiArea{qproperty-background:transparent;}
  2. 當(dāng)樣式中啟用了禁用樣式 *:disabled{xxx} 的時(shí)候,會(huì)發(fā)現(xiàn)MDI子窗體無(wú)法拉伸了,這應(yīng)該是Qt內(nèi)部的BUG,怎么解決呢,只需要重新設(shè)置MDI這個(gè)類別的禁用樣式的邊框樣式即可。QMdiSubWindow:disabled{border:8px solid rgba(0,0,0,0);}
  3. 用QProcess執(zhí)行命令或者啟動(dòng)可執(zhí)行文件,默認(rèn)寫(xiě)法不支持帶空格的路徑,比如 Program Files ,需要在這個(gè)路徑前后加上雙引號(hào)才行,估計(jì)可能內(nèi)部會(huì)用空格分割字符串導(dǎo)致解析失敗。普通路徑加上引號(hào)也能正常執(zhí)行,所以為了確保以防萬(wàn)一,統(tǒng)一加上引號(hào)即可。
QString cmd = "c:/Program Files/a.exe";
//下面這個(gè)會(huì)執(zhí)行失敗
QProcess::startDetached(cmd);

//前后加上引號(hào)就可以正常執(zhí)行
cmd = """ + cmd + """;
QProcess::startDetached(cmd);
  1. 在循環(huán)中取值,臨時(shí)變量的定義盡量在循環(huán)外層定義,每次在循環(huán)里層定義會(huì)增加開(kāi)銷(xiāo),特別是復(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比方式26倍+
//release模式下方式1比方式230倍+
  1. Qt的屬性機(jī)制非常強(qiáng)大,除了可以用來(lái)控制樣式表,也可以很方便的用來(lái)傳值,比如qml中的值傳遞,有時(shí)候我們寫(xiě)了一個(gè)通用類,希望這個(gè)類可以做很多事情,但是又希望其中有一些特殊變量存取值,一種辦法是直接定義私有變量,提供get/set接口函數(shù),還有一種偷懶的辦法就是用屬性setProperty/property,然Qt內(nèi)部從元對(duì)象數(shù)據(jù)層面自己管理,這樣不用在類中寫(xiě)對(duì)應(yīng)的變量和get/set函數(shù)。但是肯定有性能損耗,性能上肯定比變量低,所以要看具體的實(shí)際需求,如果不是非常頻繁的調(diào)用setProperty/property,通用性優(yōu)先的話,那用屬性機(jī)制會(huì)更方便。個(gè)人推薦方式三,繼承通用類,在子類中增加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();
}

//對(duì)比測(cè)試和具體的變量類型無(wú)關(guān)/int和QString類型產(chǎn)生的性能差別一樣
//setProperty比setxxx方式性能差3倍+
//property比getxxx方式性能差1.3倍
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2952

    瀏覽量

    73738
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3544

    瀏覽量

    93491
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4262

    瀏覽量

    62239
  • char
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    3698
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何將orcad轉(zhuǎn)成mentor_expedition

    使用Orcad畫(huà)電路圖后,每一個(gè)零件的PCB Footprint填入,格式如下圖所示
    發(fā)表于 06-24 17:22 ?2857次閱讀
    <b class='flag-5'>如何將</b>orcad<b class='flag-5'>轉(zhuǎn)成</b>mentor_expedition

    請(qǐng)教如何將protel PCB轉(zhuǎn)sch

    我想請(qǐng)教如何將PROTEL PCB轉(zhuǎn)成電路圖
    發(fā)表于 08-28 12:47

    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ì)過(guò)程和軟件

    如何將PowerPCB轉(zhuǎn)成Protel的詳細(xì)過(guò)程第一步:用PowerPCB打開(kāi)文件,選擇“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,請(qǐng)問(wèn)VHDL語(yǔ)言怎么寫(xiě)呢?
    發(fā)表于 05-16 18:51

    UART轉(zhuǎn)成USB的硬件設(shè)計(jì)電路

    UART轉(zhuǎn)成USB的硬件設(shè)計(jì)電路
    發(fā)表于 02-21 15:12

    如何將PDF轉(zhuǎn)成CAD

    `現(xiàn)在很多設(shè)計(jì)圖紙等操作者都需要對(duì)PDF格式得圖紙進(jìn)行二次編輯,但是PDF文件又不能直接進(jìn)行編輯修改,那我們?cè)撊绾尾僮髂兀覀兛梢?b class='flag-5'>將PDF轉(zhuǎn)成CAD文件然后再進(jìn)行轉(zhuǎn)換得操作,接下來(lái)就讓小編來(lái)具體介紹
    發(fā)表于 07-03 18:17

    如何將AD庫(kù)轉(zhuǎn)成Protell99?

    AD庫(kù)如何轉(zhuǎn)成Protell99?????
    發(fā)表于 09-04 05:36

    如何將orcad轉(zhuǎn)成mentor_expedition?

    請(qǐng)教大神如何將orcad轉(zhuǎn)成mentor_expedition?
    發(fā)表于 04-23 07:22

    請(qǐng)教一下RK3568是如何將EDP轉(zhuǎn)成VGA-out的

    請(qǐng)教一下RK3568是如何將EDP轉(zhuǎn)成VGA-out的?
    發(fā)表于 03-02 06:29

    如何將stm32的控制程序轉(zhuǎn)成51的程序?

    如何將stm32的控制程序轉(zhuǎn)成51的程序,用的是意法的傳感器,給的控制程序也是32的
    發(fā)表于 11-03 08:07

    如何將一個(gè)INT型數(shù)據(jù)轉(zhuǎn)換成2個(gè)CHAR型數(shù)據(jù)?

    如何將一個(gè)INT型數(shù)據(jù)轉(zhuǎn)換成2個(gè)CHAR型數(shù)據(jù)?
    發(fā)表于 11-03 06:20

    如何將Cadence的原理圖和PCB轉(zhuǎn)成PADS資料下載

    電子發(fā)燒友網(wǎng)為你提供如何將Cadence的原理圖和PCB轉(zhuǎn)成PADS資料下載的電子資料下載,更有其他相關(guān)的電路圖、源代碼、課件教程、中文資料、英文資料、參考設(shè)計(jì)、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發(fā)表于 04-19 08:54 ?46次下載
    <b class='flag-5'>如何將</b>Cadence的原理圖和PCB<b class='flag-5'>轉(zhuǎn)成</b>PADS資料下載

    數(shù)控直流穩(wěn)壓電源如何將交流電壓轉(zhuǎn)成直流電壓?

    數(shù)控直流穩(wěn)壓電源如何將交流電壓轉(zhuǎn)成直流電壓? 數(shù)控直流穩(wěn)壓電源是一種交流電壓轉(zhuǎn)換為直流電壓的裝置。在現(xiàn)代電子設(shè)備中,直流電壓廣泛應(yīng)用,因?yàn)樗诜€(wěn)定性、可調(diào)性和可靠性方面具有優(yōu)勢(shì)。為了滿足設(shè)備的要求
    的頭像 發(fā)表于 11-13 16:04 ?1085次閱讀