Qt development experience tips 181-185

  1. Qt is born in Linux and developed from Linux. Therefore, many Qt programmers often use Linux as their development environment, such as commonly used ubuntu and other systems, and sort out some commonly used linux commands.
commandfunction
sudo -sSwitch to the administrator. If it is sudo -i, the current directory will be changed after switching.
apt install g++Install the package (with administrator privileges). The other faction is yum install
cd /homeEnter the home directory
lsList all directories and files in the current directory
ifconfigCheck the network card information, including IP address. On windows, it is ipconfig.
tar -zxvf bin.tar.gzUnzip the file to the current directory
tar -jxvf bin.tar.xzUnzip the file to the current directory
tar -zxvf bin.tar.gz -C /homeUnzip the file to the / home directory and remember that it is in uppercase C.
tar -zcvf bin.tar.gz binCompress the bin directory into tar.gz format file (compression ratio is normal)
tar -jcvf bin.tar.xz binCompress the bin directory into tar.xz format file (high compression ratio, recommended)
tar -...J represents different compression methods, x represents decompression, and c represents compression.
gedit 1.txtOpen a text file with Notepad
vim 1.txtOpen a file with vim. Often, you can abbreviate vi.
./configure make -j4 make installFor the general compilation source code command, the first step. / configure executes the configuration script, the second step make -j4 enables multi-threaded compilation, and the third step make install installs the compiled files.
./configure -prefix /home/liu/Qt-5.9.3-static -static -sql-sqlite -qt-zlib -qt-xcb -qt-libpng -qt-libjpeg -fontconfig -system-freetype -iconv -nomake tests -nomake examples -skip qt3d -skip qtdocQt general compilation command
./configure -prefix /home/liu/Qt-5.9.3-static -static -release -nomake examples -nomake tests -skip qt3dCompact compile command
./configure --prefix=host --enable-static --disable-shared --disable-docffmpeg compile command
  1. Qt's built-in log redirection mechanism is very simple and easy to use. Since it has been used, there is no need for breakpoint debugging. It supports qdebug to output the corresponding information where necessary. Moreover, after the program is published, you can also open the debugging log to output it for viewing, etc.
//Qt5 starts to provide log context information output, such as the code file, line number, function name, etc. where the current print message is output.
//If it is release, you also need to add definitions + = QT in pro_ Only messagelogcontext can output context. Release is off by default.
//Remember not to write qdebug in the log hook function, which will lead to an endless loop.
//Log redirection is generally handled in three ways
//1: Output to a log file, such as a txt text file.
//2: Stored in the database, it can be classified and stored for query and analysis by relevant personnel.
//3: Redirect to the network. After the other party connects to the program with a gadget, all printed information is sent through tcp.

//Log redirection
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
void Log(QtMsgType type, const QMessageLogContext &context, const QString &msg)
#else
void Log(QtMsgType type, const char *msg)
#endif
{
    //Lock to prevent the crash caused by too frequent qdebug in multithreading
    static QMutex mutex;
    QMutexLocker locker(&mutex);
    QString content;

    //Here, different headers can be added according to different types to distinguish
    switch (type) {
        case QtDebugMsg:
            content = QString("%1").arg(msg);
            break;

        case QtWarningMsg:
            content = QString("%1").arg(msg);
            break;

        case QtCriticalMsg:
            content = QString("%1").arg(msg);
            break;

        case QtFatalMsg:
            content = QString("%1").arg(msg);
            break;
    }

    //Add the code file, line number and function name where the print code is located
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
    if (SaveLog::Instance()->getUseContext()) {
        int line = context.line;
        QString file = context.file;
        QString function = context.function;
        if (line > 0) {
            content = QString("Line number: %1  file: %2  function: %3\n%4").arg(line).arg(file).arg(function).arg(content);
        }
    }
#endif

    //Pass the content to the function for processing
    SaveLog::Instance()->save(content);
}

//Install log hooks and output debugging information to files for debugging
void SaveLog::start()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
    qInstallMessageHandler(Log);
#else
    qInstallMsgHandler(Log);
#endif
}

//Uninstall log hook
void SaveLog::stop()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
    qInstallMessageHandler(0);
#else
    qInstallMsgHandler(0);
#endif
}
  1. Since the c++11 standard, various syntax sugars have emerged one after another, among which lambda expression is the most widely used. Lambda expression is basically supported since Qt5. This is a new thing for the older generation of programmers who are used to c99. Here is a small understanding note.
  • Code format: capture mutable ->return-type {statement}
  • [capture]: capture list. The capture list always appears at the beginning of the Lambda function. In fact, [] is the Lambda lead. The compiler judges whether the next code is a Lambda function according to the lead. The capture list can capture variables in the context for Lambda function use.
  • (parameters): parameter list, which is consistent with the parameter list of ordinary functions. If parameter passing is not required, it can be omitted together with parentheses ().
  • Mutable: mutable modifier. By default, Lambda function is always a const function, and mutable can cancel its constancy. When using this modifier, the parameter list cannot be omitted (even if the parameter is empty).
  • ->Return type: return type. The return type of the function is declared in the form of tracking return type. We can omit it together with the symbol - > when we don't need the return value. In addition, when the return type is explicit, you can also omit this part and let the compiler deduce the return type.
  • {statement}: function body. The content is the same as that of ordinary functions, but you can use all captured variables in addition to parameters.

There are several forms of snap lists:

  • [var] indicates that the value transfer method captures the variable var.
  • [] indicates that the value transfer method captures all variables of the parent scope (including this).
  • [& var] refers to the reference passing capture variable var.
  • [&] indicates that the reference passing method captures all variables of the parent scope (including this).
  • [this] indicates that the value transfer method captures the current this pointer.
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //Click the button without parameters
    connect(ui->pushButton, &QPushButton::clicked, [] {
        qDebug() << "hello lambda";
    });

    //Button click with parameters
    connect(ui->pushButton, &QPushButton::clicked, [] (bool isCheck) {
        qDebug() << "hello lambda" << isCheck;
    });

    //Custom signal band parameters
    connect(this, &MainWindow::sig_test, [] (int i, int j) {
        qDebug() << "hello lambda" << i << j;
    });

    emit sig_test(5, 8);
}
  1. Due to the large number of QT versions, sometimes in order to be compatible with multiple versions or even across Qt4/Qt5/Qt6, some header files or class names have changed or added, and the judgment of QT version needs to be used. Note that if QT is used in the header file_ VERSION_ Check needs to introduce #include "qglobal.h" first, otherwise the compilation fails because QT_ VERSION_ The check function is in the qglobal.h header file.
//At least include qglobal.h. theoretically, all classes of Qt include this header file, so you can also introduce other header files of Qt, such as qobject.h
#include "qglobal.h"
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include "qscreen.h"
#else
#include "qdesktopwidget.h"
#endif
  1. When using QString to convert to char * or const char *, you must remember to score two steps to complete the lesson of blood. In a scene, because there is no two steps, the phenomenon is that the debug and release of msvc are abnormal, and the debug and release of mingw and gcc are normal. This is very speechless. Find the problem for a long time, and the comparison method and exclusion method are reasonable, or there are problems.
  • The content of QString before conversion has nothing to do with Chinese or English. If there is a problem, it is the same.
  • QByteArray has nothing to do with the specific type in the conversion. The problems of toUtf8, toLatin1, toLocal8Bit and other methods are the same.
  • After conversion, it does not matter whether char * or const char *, and the problem is the same.
  • The randomness of the problem occurs, and the probability of debug ging is greater in theory.
  • According to the analysis of the cool code boss, msvc will be populated after the memory is released for debug ging, while release will not.
QString text = "xxxxx";
//The following conversion is likely to have problems
char *data = text.toUtf8().data();
//There will certainly be no problem with the two-step conversion
QByteArray buffer = text.toUtf8();
char *data = buffer.data();
const char *data = buffer.constData();

Keywords: Linux Qt Ubuntu

Added by dc519 on Sat, 30 Oct 2021 14:34:00 +0300