Qt development experience tips 121-130

  1. QLineEdit can be used for many special processing purposes besides simple text boxes.
  • Restrict input. Only IP addresses can be entered.
  • To limit the input range, it is highly recommended to use QRegExpValidator regular expression for processing.
//Limiting input for expression
QString str = "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";
ui->lineEdit->setValidator(new QRegExpValidator(QRegExp(str)));
//For space occupation
ui->lineEdit->setInputMask("000.000.000.000");

#if 0
//The following code failed to set the floating point range limit
ui->lineEdit->setValidator(new QDoubleValidator(20, 50, 1));
#else
//The following code sets the floating point range limit successfully
QDoubleValidator *validator = new QDoubleValidator(20, 50, 1);
validator->setNotation(QDoubleValidator::StandardNotation);
ui->lineEdit->setValidator(validator);
#endif
//The following code sets the integer range limit successfully
ui->lineEdit->setValidator(new QIntValidator(10, 120));

//In fact, the above code has many defects. It can only limit the input of decimals and cannot set the value range. It's very fucked
//We need a powerful QRegExpValidator

//Limit the input range of floating-point number to [- 180180]
QRegExp regexp("^-?(180|1?[0-7]?\\d(\\.\\d+)?)$");
//The input range of floating-point number is limited to [- 90,90] and the last 4 decimal places
QRegExp regexp("^-?(90|[1-8]?\\d(\\.\\d{1,4})?)$");
QRegExpValidator *validator = new QRegExpValidator(regexp, this);
ui->lineEdit->setValidator(validator);
  1. In controls inherited from QAbstractItemView, such as QTableView and QTableWidget, if the text exceeds the width of the corresponding item, the ellipsis will be displayed automatically. If you want to quickly display the complete text, you can double-click between the split line of this column and the next column to automatically adapt to the maximum width. If it is Qt5 14 or later, you will find that the calculation rule of displaying ellipsis has changed. If it is an English string beginning with rtsp and http, ellipsis will be displayed in advance under the same column width, such as string rtmp://58.200.131.2:1935/livetv/cctv1 , will be displayed as rtmp://... , which will be displayed as rtmp://58.200.131 ... , Many times we don't want to see annoying ellipsis. We can set it to cancel.
//Cancel auto wrap
tableView->setWordWrap(false);
//Do not display ellipsis beyond text
tableView->setTextElideMode(Qt::ElideNone);
  1. When QVideoWidget plays a video, the screen may flicker. A property needs to be set on the form for playing the video.
QVideoWidget *videoWidget = new QVideoWidget;
videoWidget->setAttribute(Qt::WA_OpaquePaintEvent);
  1. There are tens of thousands of QT bugs. There is no need to make a fuss, and they are basically not encountered. Most of them are special extreme cases, specific application scenarios, and even you will encounter some cases where debug can release and report errors, and some cases where release can debug but report errors. The most magical thing is that first debug and report errors, then release is normal, and then go back and use debug, You need to activate it with release! The way of learning programming is a bumpy road. Keep filling the pit and try to avoid the pit! Most of the time, many seemingly pits are actually caused by not paying attention to the details.

  2. The default sorting in the Qt attempt is based on the ASCII of the string. If it is an IP address, 192.168.1.117 will appear in front of 192.168.1.2. If you want to avoid this situation, one way is to take the address at the end and convert it into an integer and compare the size. The disadvantage is that the dishes will be stopped across the network segment, and 192.168.2.65 will appear in front of 192.168.1.70, The ultimate solution is to convert the IP address into an integer and compare the size.

QString QUIHelper::ipv4IntToString(quint32 ip)
{
    QString result = QString("%1.%2.%3.%4").arg((ip >> 24) & 0xFF).arg((ip >> 16) & 0xFF).arg((ip >> 8) & 0xFF).arg(ip & 0xFF);
    return result;
}

quint32 QUIHelper::ipv4StringToInt(const QString &ip)
{
    int result = 0;
    if (isIP(ip)) {
        QStringList list = ip.split(".");
        int ip0 = list.at(0).toInt();
        int ip1 = list.at(1).toInt();
        int ip2 = list.at(2).toInt();
        int ip3 = list.at(3).toInt();
        result = ip3 | ip2 << 8 | ip1 << 16 | ip0 << 24;
    }
    return result;
}
  1. In the main QWidget form, if you directly set the background picture of qss, the preview is visible and the operation has no effect. You need to put another widget on the main widget and set the qss picture on the new widget. If it is Dialog or QMainWindow form, you can directly set the background picture of qss, and the preview and operation effects are the same.

  2. Qt provides a qdebug mechanism to directly output print information, which makes up for the weakness of QtCreator debugging, and seamlessly connects the log hook to output the scheduled print information to the log file during on-site operation. Sometimes in the development stage, you don't want to see piles of print information. The most stupid way is to comment out the places of qdebug line by line, In fact, you can directly add a line to pro to disable the qdebug output of the whole project.

#Disable qdebug printouts
DEFINES += QT_NO_DEBUG_OUTPUT
  1. Qt in use_ NO_ DEBUG_ After disabling all print information with the output keyword, you can save a lot of expenses. Sometimes you want to see print information in very few places after disabling print information. What should you do? In fact, Qt_ NO_ DEBUG_ The output of qdebug disabled by output, Qt and other printing information, such as qInfo, qWarning and qCritical, are not affected, that is to say, it is good to use qInfo to output information in a few places that need to be printed. Special note: after qFatal prints the information, the program will end automatically.
qDebug() << "qDebug";
qInfo() << "qInfo";
qWarning() << "qWarning";
qCritical() << "qCritical";

qDebug("qDebug");
qWarning("qWarning");
qCritical("qCritical");
  1. Qt's pro file can add various processes to make the configuration more convenient, such as specifying the path of the output file, so that it will not be found in a pile of temporary files generated by compilation.
#Disable qdebug printouts
DEFINES     += QT_NO_DEBUG_OUTPUT

#The custom define variable can be used throughout the project
#The pro file can judge the contents (definitions, videovlc) {}
#The code file can be judged in this way #ifdef videovlc
DEFINES     += videovlc1 videoffmpeg

#Turn off compilation warning prompt. If you don't see it, it's clean
CONFIG      += warn_off

#Specify that the compiled files are stored in the temp directory by category
MOC_DIR     = temp/moc
RCC_DIR     = temp/rcc
UI_DIR      = temp/ui
OBJECTS_DIR = temp/obj

#Specify the executable file generated by compilation to the bin directory
DESTDIR     = bin
  1. Qt also encapsulates a lot of messages in the operating system layer, which can be directly received and processed (if interception is needed, the API of the corresponding operating system should be used, such as mouse and keyboard hook), such as system sleep and wake-up.
//Main form header file
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
#ifdef Q_OS_WIN
    bool winEvent(MSG *message, long *result);
#endif

//Main form implementation function
#ifdef Q_OS_WIN
#include "Windows.h"
#endif

bool frmMain::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    if (eventType == "windows_generic_MSG") {
#ifdef Q_OS_WIN
        MSG *msg = static_cast<MSG *>(message);
        //qDebug() << TIMEMS << msg->message;
        if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST) {
            //Automatic minimization during system sleep can avoid possible problems in the program
            this->showMinimized();
        } else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) {
            //Automatically turn on after sleep wakes up
            this->showNormal();
        }
#endif
    } else if (eventType == "NSEvent") {
#ifdef Q_OS_MACOS
#endif
    }
    return false;
}

#ifdef Q_OS_WIN
bool frmMain::winEvent(MSG *message, long *result)
{
    return nativeEvent("windows_generic_MSG", message, result);
}
#endif
  1. Qt's pro project management configuration file can also add various operations and configurations before and after compilation, mainly through QMAKE_POST_LINK and QMAKE_PRE_LINK, the functions they support and their writing methods. You can search qmake Function Reference in QtCreator help to see the detailed description.
  • QMAKE_PRE_LINK indicates the content executed before compilation
  • QMAKE_POST_LINK represents the content to be executed after compilation
srcFile1 = $$PWD/1.txt
srcFile2 = $$PWD/2.txt
dstDir = $$PWD/../bin
#The conversion path slash is required on windows, which is not required by other systems
srcFile1 = $$replace(srcFile1, /, \\);
srcFile2 = $$replace(srcFile2, /, \\);
dstDir = $$replace(dstDir, /, \\);

#Execute copy before compilation. Multiple copies can be separated by & & symbol
QMAKE_PRE_LINK += copy /Y $$srcFile1 $$dstDir && copy /Y $$srcFile2 $$dstDir
#Execute copy after compilation. Multiple copies can be separated by & & symbol
QMAKE_POST_LINK += copy /Y $$srcFile1 $$dstDir && copy /Y $$srcFile2 $$dstDir

Qt development experience open source homepage (continuously updated):

  1. https://gitee.com/feiyangqingyun/qtkaifajingyan
  2. https://github.com/feiyangqingyun/qtkaifajingyan

Keywords: C++ qmake

Added by trassalg on Thu, 03 Mar 2022 23:24:05 +0200