- 編程的過程中經常遇到需要將QString轉成char *或者const char *的情況,在轉換成QByteArray後調用.data()或者.constData()函數進行轉換,這裏需要注意的是,如果轉換類型是const char *儘管用data()不會出錯,會給你自動轉換,但是還是不建議,因爲深拷貝了一份,理論上增加了內存開銷,如果字符串長度小還好,一旦很長,這個開銷挺大,這是個好的編程習慣。
//查閱代碼得知data函數有兩個重載
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)
{
}
//至於什麼時候調用.data()會淺拷貝,酷碼大佬說是當QByteArray被const修飾的時候
const QByteArray data;
//淺拷貝
const char *d = data.data();
//酷碼大佬補充:自Qt 5.7版本以來,引入了qAsConst函數,專用於無腦轉換。
//這個函數實現了C++17標準中的std::as_const()函數的功能,將一個非常量的左值轉爲常量的左值。
//增加qAsConst函數是爲了Qt自己的非const 的容器能實現C++11標準的基於範圍的循環。
//該函數主要用於qt容器在隱式共享中不被detach。
QString s = "abc";
//下面會深拷貝引起性能損失
for (QChar ch : s)
//不會深拷貝
for (QChar ch : qAsConst(s))
//下面也是淺拷貝,但是在編程時、在現實中,聲明爲const往往不容易做到。
const QString s;
for (QChar ch : s)
//總結:對Qt自己實現的容器如:QVector、QMap、 QHash、QLinkedList、QList等,如果一定要用基於for(var : container)範圍的循環,則請用如下形式:
for (var : qAsConst(container))
-
新版的Qt6.5在ubuntu上編譯運行程序後會提示 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. ,無法正常彈出窗體程序,你需要主動安裝xcb的相關庫。sudo apt install libxcb*
-
有些場景下我們需要在 QApplication a(argc, argv); 前面執行一些處理,比如 QApplication::setAttribute 就必須在最前面執行,而很多時候這個設置的參數不能改寫死,畢竟現場的環境千差萬別,希望通過配置文件來配置,那麼問題來了,讀取配置文件一般需要指定路徑才能正常讀取到,如果是 ./ 這種,很可能未必是應用程序的當前路徑,如果你是雙擊運行的程序,那肯定是應用程序的當前路徑,不是雙擊運行那就是系統環境中的當前路徑,意味着你開機啓動或者用system、QProcess等方式在開機後調用啓動的話,就未必正確了。爲了保證這個路徑的正確,必須從main函數的 argv 第一個值獲取,通過查閱Qt自身代碼中獲取路徑,也是從這個參數獲取。
//程序最前面獲取應用程序路徑和名稱
static void getCurrentInfo(char *argv[], QString &path, QString &name);
//程序最前面讀取配置文件節點的值
static QString getIniValue(const QString &fileName, const QString &key);
static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString());
void QUIHelper::getCurrentInfo(char *argv[], QString &path, QString &name)
{
//必須用fromLocal8Bit保證中文路徑正常
QString argv0 = QString::fromLocal8Bit(argv[0]);
QFileInfo file(argv0);
path = file.path();
name = file.baseName();
}
QString QUIHelper::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 QUIHelper::getIniValue(char *argv[], const QString &key, const QString &dir)
{
QString path, name;
QUIHelper::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 = QUIHelper::getIniValue(argv, "OpenGLType").toInt();
QUIHelper::initOpenGL(openGLType);
QApplication a(argc, argv);
...
}
- 當我們對QTableView/QTreeView/QTableWidget/QTreeWidget某行選中後,會發現某些單元格設置的前景色被覆蓋了,比如設置的紅色,一旦選中就變成了白色,這肯定不是我們想要的,需要用自定義委託將其去掉。
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);
}
//對所有單元格設置該委託
ui->tableWidget->setItemDelegate(new ItemDelegate);
- 有些時候我們需要在項目文件比如pro/pri中識別當前Qt套件是否存在某個模塊以及是否引入過某個模塊,存在則引入,同時也希望代碼中也能識別是否引入過某個模塊比如sql模塊,判斷後再進行對應的處理。
//項目文件中判斷
//如果當前套件中有multimedia模塊則引入multimedia模塊
qtHaveModule(multimedia) {QT += multimedia}
//在項目文件中已經通過 QT += multimedia 引入過模塊
contains(QT, multimedia) {}
//代碼文件判斷
#ifdef QT_MULTIMEDIA_LIB
qDebug() << "multimedia module is enabled";
#else
qDebug() << "multimedia module is not enabled";
#endif
國內站點:https://gitee.com/feiyangqingyun
國際站點:https://github.com/feiyangqingyun