Qt development experience tips 271-275

  1. In the process of programming, it is often necessary to convert QString to char * or const char *. After converting to QByteArray, call the .data() or .constData() function to convert. It should be noted here that if the conversion type is const char * Although using data() will not make mistakes and will automatically convert it for you, it is not recommended, because a deep copy will theoretically increase the memory overhead. If the length of the string is small, it is fine. That's a lot of overhead, and it's a good programming practice.
//查阅代码得知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. The new version of Qt6.5 will prompt qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in “” even though it was found. after compiling and running the program on ubuntu, and the window program cannot pop up normally, you need to actively Install related libraries of xcb. sudo apt install libxcb*

  2. In some scenarios, we need to perform some processing before QApplication a(argc, argv); For example, QApplication::setAttribute must be executed at the top, and in many cases, the parameters of this setting cannot be rewritten. Configuration file to configure, then the problem is coming. Generally, you need to specify the path to read the configuration file. If it is ./, it may not be the current path of the application. If you double-click the program to run, then It must be the current path of the application. If it is not double-clicked to run, it is the current path in the system environment, which means that if you start it after booting or use system, QProcess, etc. to call and start after booting, it may not be correct. In order to ensure the correctness of this path, it must be obtained from the first value of argv of the main function, and the path obtained by consulting Qt's own code is also obtained from this parameter.

//程序最前面获取应用程序路径和名称
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. When we select a row of QTableView/QTreeView/QTableWidget/QTreeWidget, we will find that the foreground color set by some cells is covered, such as the set red, once selected, it becomes white, which is definitely not what we want. It needs to be removed with a custom delegate.
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. Sometimes we need to identify in the project file such as pro/pri whether there is a module in the current Qt suite and whether it has been introduced. If it exists, it is imported. At the same time, we also hope that the code can also identify whether a module has been introduced, such as the sql module. , and then perform corresponding processing after judgment.
//项目文件中判断
//如果当前套件中有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

Domestic site: https://gitee.com/feiyangqingyun
International site: https://github.com/feiyangqingyun

Guess you like

Origin blog.csdn.net/feiyangqingyun/article/details/131299173