Qt Programming (2)-Initial Advancement

Preface

  • Through the previous article, we have a preliminary understanding of Qt, Qt Programming (1)-Understanding
  • Here we start to study Qt in depth. As we know before, the important things in Qt are signals and slots, which are connected through the connect() function. Here we take a closer look at signals and slots

1. Qt custom signals and slots

1. Custom signals and slots

  • 1. First, you need to create two classes, a signal class and a slot function class. Right-click the project->Add New, and create a new class
    Insert image description here
  • 2. Set the attributes of the class: class name, parent class, location.
    Insert image description here
    In the declared slot function, right-click the function name, select Refactor->Add definition in the .cpp file.
    Custom signal class:
    Add a signal declaration in the header file of ZMSignals. , no need to implement
    Insert image description here
    a custom slot function class:
    add the definition and implementation of the custom slot function in the header file and source file of the ZMSlots class.
    Insert image description here

Insert image description here

  • 3. Connect signals and slots.
    Signals and slots need to be connected through a window, eg: widget, window, etc.
//emit是发送信号的标识,不写会报警告,版本问题,(非必须)
 emit zmSignal.zm_sig_start();

Insert image description here

2. Customized signal band parameter overloading problem

  • 1. Add overloaded signal and slot functions
    Insert image description here
    Insert image description here
  • 2. It was found that an error was reported when connecting. It was because there was ambiguity in the context overloading function when connecting.
    Insert image description here
  • 3. We can use a function pointer with parameters to point to the function we want to point to to eliminate ambiguity. I personally recommend the first of the following two methods.
#if 1 //两个方式一样,只是指针函数开放与不开放的问题
    //方法一:

    //设置两个带参数的函数指针
    void (ZMSignals::*str_sig_start)(QString) = &ZMSignals::zm_sig_start;
    void (ZMSlots::*str_slot_accept)(QString) = &ZMSlots::zm_slot_accept;

    //关联带参数的函数指针
    w.connect(&zmSignal, str_sig_start, &zmSlot, str_slot_accept);
#else
    //方法二:强制转换型,代码可读性低
    w.connect(&zmSignal, ( void (ZMSignals::*)(QString)) &ZMSignals::zm_sig_start, &zmSlot, (void (ZMSlots::*)(QString)) &ZMSlots::zm_slot_accept);
#endif

Insert image description here

3. Summary of function overloading issues

  • Pay attention to which function the signal overloaded function pointer points to. When connecting the signal of the overloaded function, you must indicate which slot function is connected.

4. Extension of signals and slots

1. Signal connection:

  • We trigger a signal by clicking a button, and then trigger the slot function corresponding to the signal through the connect connection between the signal and the slot. That is: signals connect signals. A message signal can be bound to multiple slots. Similarly, a slot function can also be bound to multiple message signals. ( Many-to-many relationship )
    eg: Triggering a button click simultaneously triggers the execution of the slot function corresponding to ZMSlots, and triggers the closing slot function corresponding to MainWindow.
    Insert image description here

2. Signal disconnection:

  • The connection can be disconnected through the disconnect function, which is used in the same way as the signal connection connect.
  • disconnect(signal sender, signal, signal receiver, slot function);
    Insert image description here

3. Parameters of signals and slots

  • What the signal sends is what the slot function receives, and the types must be consistent.
  • The number of parameters of the signal can be more than the number of parameters of the slot function, but the parameter types of the same number of parameters must correspond one to one. The reverse is not possible.

2. Lambda function

  • In order to solve the problem of transmission and connection of various signals in the project, in large projects, excessive use of signal connection and transmission will reduce the readability of the project and increase the cost of familiarity.

1. Understanding Lambda functions

  • Lambda function, also called Lambda expression, is an anonymous function (function without a name), which is different from traditional functions.
  • Lambda expressions are a concept introduced after C++11 and are used to define and create anonymous function objects.

2. Lambda expression structure:

[Capture list] (parameter) mutable-> return type {function body},
eg:

[](){
    
    
	qDebug("Hello Qt");
}
  • [], identifies the beginning of a Lambda anonymous function. This must be present and cannot be omitted. The function object parameter is passed to the constructor of the function object class automatically generated by the compiler. Function object parameters can only use local variables visible in the scope where the Lambda is defined, including this of the class where the Lambda is located.
  • [] The corresponding parameters in the square bracket function object have the following forms:
    • Empty , no function object parameters are used
    • = , the function body uses visible local variables in the scope of Lambda, including the value-passing method of this of the class, which is equivalent to the compiler giving all local variables in the scope of Lambda**Assignment**One copy for the Lambda function
    • & , the function body uses visible local variables in the scope of Lambda, including the reference method of this of the class, which is equivalent to the compiler giving all local variables in the scope of Lambda**quote**One copy for the Lambda function
    • this, the member variable inside the Lambda can be used in the function body
    • a , not a letter, but refers to a specific variable a, copy a variable a in Lambda and use it
    • &a , reference variable a in Lambda
    • a, &b , copy a, reference b
    • =, &a, &b , except for a and b references, other variables are copied.
    • &,a,b , except for copies of a and b, other variables are referenced.
  • mutable: mark can be changed

3. Why use Lambda function?

  • Some functions are only used temporarily and their business logic is very simple, so there is no need to give them names. Some operations can also be simplified in Qt.

4. Lambda instance

Insert image description here
Insert image description here

3. Lambda function extension

1. Lambda return value

Insert image description here

The program can output the result normally: 40;

  • important point:
    • -> is a sign with a return value, int is the return value type, and is returned directly in the function.
    • The last () is to call the function. Without (), it is not a function call. The function here can be called directly after being defined.

Lambda expression, realizing Fibonacci numbers

    //斐波那契数:Fibonacci数
    int a=0, b=1;
    [](int& a,int& b, int count){
    
    
        int ret = 0;
        for (int i =0; i<count; i++) {
    
    
            ret = a+b;
            a=b,b=ret;
            qDebug()<<ret;
        }
    }(a, b, 10);//函数调用时,传a,b进到Lambda表达式里

operation result:
Insert image description here

2. Application of Lambda

  • A signal without parameters calls a slot function with parameters. At this time, Lambda is used to
    Insert image description here
    implement the principle analysis: because the button click has no parameters, the anonymous function also has no parameters, but a signal with parameters is called in the anonymous function.

3. QString to char*

  • Because QDebug will include the double quotes of QString when printing.
    Insert image description here
  • Among some public methods in the QString class, there is a toUtf8 method, which returns a QByteArray and is first converted into a byte array. Then there is a data method, which calls the data method and then converts the array into char*
    Insert image description here

4. Lambda meaning

  • 1. Make the code more concise and efficient
  • 2. If connect, the receiver of the signal is this, this can be omitted.
  connect(btn, &QPushButton::clicked,[=](){
    
     //信号接收者为this,可以省略不写
        this->close();
    });//发送信号

Insert image description here

4. Commonly used controls

1. QTextEdit control

  • QTextEdit: text edit box,
    Insert image description here
  • Example:
    Insert image description here

2,QMainWindow

  • QMainWindow is the main window class that provides an interface for users, including a menu bar (menubar), multiple toolbars (toobar), multiple riveted components (dockwidgets floating windows), a status bar (status), and a central widget (centralwidget) , is the basis of the app, eg: text editor, picture editor, etc.
    Insert image description here

3. Menu bar (QMenuBar)

  • There is only one menu bar, and the setting method is: setMenuBar
    Insert image description here

4. Add toolbar (QToolbar)

  • The toolbar can be dragged at will, and can be placed on the left, upper, lower, or right side of the software, or even float in the app interface.
  • The difference between a toolbar and a menu bar : there can only be one menu bar, and it is at the top; while there can be multiple toolbars, and their positions are diverse. So the setting method is addToolBar
    Insert image description here

5. Add status bar (QStatusBar)

  • There is and can only be one status bar added, so the setting method is setStatusBar.
    Insert image description here

  • Add status bar,Due to differences in systems and when the number of Chinese characters and Chinese symbols is an odd number, garbled characters may easily appear.

    • Solution 1: Reset the encoding rules in the editor, and add all Chinese characters in front of themu8, that’s it
      Insert image description here
      Insert image description here

    • Solution 2: Use the QStringLiteral() method, because it is implemented internally using Lambda expressions, and high-frequency calls affect performance.
      Insert image description here

6. Riveting components and central components (QDockWidget, centralWidget)

1. Riveted components (dockWidget)

-Riveted components, central components, and floating windows have the same meaning. By checking the Qt Assistant documentation, we see that QDockWidget is based on QWidget.There can be multiple floating windows, so addDockWidget
Insert image description here

  • When there is a riveted component, it will become floating when dragged to the middle, and the default docking place is a bit strange. This is because, in QMainWindow, we have not added the center widget. The default center widget is empty, so it is directly at the top.
    Insert image description here
  • For the settings of riveted parts, query the Qt assistant documentation, which is the same as the toolbar.

2. CentralWidget

  • In QMainWindow, there is a central component, but this central component is not a specific central component. Instead, we can set a specific component as the central component.There can only be one central widget, so setCentralWidget
    Insert image description here
    Insert image description here

5. Engineering and interface UI

1. UI designer

  • There will be a .ui file in every project, which is actually a Qt interface file. When the file is opened, the Qt ui designer is automatically launched. Editing controls in this designer will be much more convenient and intuitive, and greatly improve development efficiency.
    Insert image description here
    Insert image description here
  • After adding a tableview
    Insert image description here
    Insert image description here
    and setting a new action, drag the action directly to the corresponding position.
  • Pay more attention to the use of property settings, the use of signals and slots, and the use of right-click property settings.

2. Add Qt resource files

  • There are two ways to add resources: source code addition, and adding using UI designer. For example: a QAction object, add an icon to it, or set an icon. You can add multiple representatives. Generally speaking, a tool or a tab is one Icon, therefore, we should set the icon, that is, set the icon, then the method is set at the beginning, setIcon

1. How to add source code

  • Adding images to the source code is limited to paths. Using relative paths requires some settings, and once the path is modified, the images may not be loaded.
    Insert image description here

2. How to add UI designer

  • To add a prerequisite, you need to create a Resource File, right-click the project->add New->Qt->Qt Resource File, create a new project resource file, and then put the image resources into it.
    Insert image description here
  • After creating the resource file, set the prefix and add image resources. Remember to save after adding the resources.
    Insert image description here
    Insert image description here
  • After saving the resources added in the previous step, open the UI designer and add an icon to the "Save" option.
    Insert image description here
    Insert image description here
  • After selecting the icon, you can see it directly in the UI designer.
    Insert image description here
  • After adding the resource file, we can also use code to access the resource file.
    Insert image description here
    When constructing QIcon, we need ": + prefix name + resource path"

3. Dialog box – modal & non-modal

  • In graphical user interfaces, dialog boxes are distinctive views used to display information to the user or obtain user input responses when needed. constitutes human-computer interaction.
  • Standard dialog boxes are a series of dialog tools built into Qt to simplify development.
  • Qt's built-in dialog boxes include:
    • QColorDialog select color dialog
    • QFileDialog selects a file or directory
    • QFontDialog select font
    • QInputDialog allows the user to enter values ​​and returns them
    • MessageBoxDialog modal dialog box, used to display information, consultation or warning, etc.
    • etc.
  • Modal: User interaction is blocked in the current dialog box
  • Non-modal: The user can jump out of the current dialog box and interact in other dialog boxes.

1,QDialog

Insert image description here

  • Qt's entry main function returns an exec, which keeps Qt's main window displayed. At that time, there is an infinite loop in exec. It waits for control messages until it receives the closing message, and then exits the window. Otherwise, it keeps looping. Blocked in the message, so that the original window cannot continue to execute.
  • Note, the problem of lambda expression scope, (stack)
    Insert image description here
  • Pay attention to the hidden dangers of memory leaks and add methods to delete components.
    Insert image description here

2,QMessageBox

  • 1. Get to know
    • QMessageBox is a modal dialog box , which is mainly used in apps to provide display information, pop-up queries, warnings, etc. For example: when we edit text in Notepad and click Close if it is not saved, the app will pop up a QMessageBox dialog box to ask whether to save the text.
    • QMessageBox is a dialog box based on the QDialog class
      Insert image description here
  • 2. Use
    Insert image description here
    • Example:
      QMessageBox::information(this, "ask", "what are you doing?");, information, question, warn, and ceramic are all static functions and have their own memory controls, so they can be called directly using classes. No need to create it in the heap anymore
      Insert image description here
    • Pay attention to the return type of static member functions and how to call them
    • The meaning of parameters
      Insert image description here
    • Part of the source code:
 connect(ui->pb02, &QPushButton::clicked, [=](){
    
    
        //在堆中创建msg,需要控制释放,但对于模态来说,会阻塞函数不能结束,如果用户触发结束后,自动跟随函数释放内存。因此不建议这么写
//        QMessageBox* msg = new QMessageBox(this);
//        msg->information(this, "询问","你在干嘛?");

        //比较合理的编写方式,information为静态函数,因此可以直接使用类调用
        int ret = QMessageBox::information(this, "提示","你上班摸鱼5分钟了,请合理安排时间!", QMessageBox::Yes|QMessageBox::No);
        if (ret == QMessageBox::Yes) {
    
    
            qDebug()<<"好的,知道了!";
        } else {
    
    
            qDebug()<<"就是为了让老板知道!";
        }
    });

    connect(ui->pb03, &QPushButton::clicked, [=](){
    
    

        //比较合理的编写方式,question为静态函数,因此可以直接使用类调用
        QMessageBox::question(this, "询问","你在干嘛?");

    });
    connect(ui->pb04, &QPushButton::clicked, [=](){
    
    

        //比较合理的编写方式,warning为静态函数,因此可以直接使用类调用
        QMessageBox::warning(this, "警告","注意:你上班摸鱼10分钟了,可能要被老板发现了");
        critical_func(this);
    });

void critical_func(QWidget* widget)
{
    
    

//    QMessageBox::critical(widget, "致命","不好,你摸鱼被老板发现了!");

    QMessageBox* msg = new QMessageBox(widget);
    msg->resize(200,100);

    QPushButton* btn = new QPushButton();
    btn = msg->addButton("确定", QMessageBox::AcceptRole);
    msg->show();

    widget->connect(btn,&QPushButton::clicked,widget, [=](){
    
    
        msg->critical(widget, "致命","不好,你摸鱼被老板发现了!");
    });
}

3,QColorDialog

  • In the static function area in QColorDialog:
    Insert image description here
  • Four parameters: color, parent class, title name, ColorDialogOptions color options, if you only call getColor(), defaults are added respectively. The return value is QColor.
static QColor getColor(const QColor &initial = Qt::white,
                           QWidget *parent = nullptr,
                           const QString &title = QString(),
                           ColorDialogOptions options = ColorDialogOptions());

Insert image description here

4,QFileDialog

  • Search QFileDialog in the Qt Assistant, static function area, getOpenFileName and getOpenFileNames are the two methods we use to obtain the file path + file name. To operate the file, we only need to obtain the path + file name:
    Insert image description here
  • Two functions, one returns QString without adding s, and the other function adding s returns a QStringList, that is, one returns a specific file and the other returns a file list.
static QString getOpenFileName(QWidget *parent = nullptr,
                                   const QString &caption = QString(),
                                   const QString &dir = QString(),
                                   const QString &filter = QString(),
                                   QString *selectedFilter = nullptr,
                                   Options options = Options());

Corresponding to five parameters:
parent class: usually this
caption: title
dir: default path
selectedFilter: file filtering, filtering and displaying files with suffixes that meet the conditions
opthons: filer, the default is enough

  • Simple example:
    Insert image description here

6. Summary

  • 1. Through a preliminary understanding of Qt, we learned about some common controls developed in Qt interface, the inheritance relationship of controls and the open methods in the controls.
  • 2. There are two ways in engineering development. When programming, we use code or use UI designer to design according to different demand scenarios (a game between performance and development speed)
  • 3. The Qt Assistant document is very practical and it is recommended to use it more.
  • 4. Here we only have some understanding of Qt, involving programming design patterns and more aspects of optimizing performance, which have not been reflected in this content. Subsequent accounts will be continuously updated. Interested students please also pay attention.

Guess you like

Origin blog.csdn.net/MOON_YZM/article/details/130592369