Qt 開発エクスペリエンスのヒント 271 ~ 275

  1. プログラミングの過程では、QString を char * または const char * に変換する必要があることがよくあります。QByteArray に変換した後、.data() または .constData() 関数を呼び出して変換します。 type は 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))
  1. Qt6.5 の新しいバージョンでは、ubuntu 上でプログラムをコンパイルして実行した後、qt.qpa.plugin: Could notload the Qt platform plugin “xcb” in “” but it was found. というプロンプトが表示され、ウィンドウ プログラムがポップアップできません通常、xcb の関連ライブラリを積極的にインストールする必要があります。sudo apt install libxcb*

  2. 一部のシナリオでは、QApplication a(argc, argv) の前に何らかの処理を実行する必要があります。たとえば、QApplication::setAttribute を先頭で実行する必要があり、多くの場合、この設定のパラメーターを書き換えることはできません。構成ファイルを読み込む場合、問題が発生します。通常、構成ファイルを読み取るにはパスを指定する必要があります。それが ./ の場合、プログラムをダブルクリックして実行する場合、それは必ずしもアプリケーションの現在のパスであるとは限りません。 , その後、アプリケーションの現在のパスである必要があります。ダブルクリックして実行しない場合は、システム環境内の現在のパスです。つまり、起動後に起動するか、システム、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);
    ...
}
  1. 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);
  1. 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

おすすめ

転載: blog.csdn.net/feiyangqingyun/article/details/131299173