About removing the title bar in the UI interface (QT, PyQT) to realize customization, maximization, minimization, closing and other function buttons

Why design and implement the title bar yourself

  • Whether you use qtdesigner or create a Qwidget directly in the program, the interface generated by qt program will generate a default title bar.

  • The title bar should essentially be a border, but ico and title can be displayed on the border, and operations such as maximization and minimization can be performed.

  • The color of the title bar changes with the theme of the computer system, and the form is fixed. If you set a unified background and style for the interface, the title bar will be very abrupt and ugly. Therefore, if we want to obtain a harmonious and unified UI interface, we'd better remove the default title bar generated by the system and reproduce the functions attached to the default title bar by ourselves.

  • --The default title bar appears abrupt in a unified background

  • --Customize the title bar. You can design the size, icon and position of the keys, which can be more unified with the background

If you want to use your own, you must first get rid of others

  • --The following statements can be used in QT programming to remove the default border automatically generated by the system.
MainWindow::setWindowFlags(Qt::FramelessWindowHint);//Hide border 
  • By modifying the input of setWindowFlags, we can also modify the border to a special style, such as with only one close button.

  • --In python, the statement is written as follows:

self.setWindowFlags(Qt.FramelessWindowHint) # Hide border 

What will we lose after removing the title bar

  • As mentioned earlier, the essence of the title bar is a border, or a group. This border is used as a limit. The UI content is nested in the border, and the border is "suspended" on the desktop.
  1. Therefore, after removing the border, the UI interface will lose the ability to adjust the size because of the loss of the border. The performance is that the mouse cannot select the edge of the interface to drag the edge to change the size.

  2. At the same time, because changing the position of the interface on the desktop was originally realized by the border, after removing the border, there is no clear layout relationship between the UI and the desktop, and the interface content cannot be moved.

  3. The functions of maximizing (restoring), minimizing and closing the original program are realized by the buttons in the title bar. After removing the title bar, the mode of such operation interface will disappear, but we can still right-click the operation interface through the status bar at the bottom.

  4. In conclusion, after removing the title bar, we will not be able to maximize (restore), minimize and close the interface through buttons, drag the interface or change the size of the interface, which will also be our functions to be realized in the future.

How to maximize (restore), minimize, close and other operations in the program

  • QT is a foolproof interface drawing method. For the common drawing, closing and other operations in the interface, there are a series of events in QT architecture that can be called and modified to help writers easily realize these functions. Therefore, after removing the title bar, we only need to add the desired button in the interface, name it and put it in the desired position. By modifying the style and label of the button by setting the style, we can replace the default title bar by calling the events described above.

1. Place the button, adjust the position, and modify it to the style you want.

  • --Here is a section of my commonly used button style sheet, which defines the background color of the button, the mouse hovering effect and the pressing effect respectively.
QPushButton{background-color:rgba(0,0,0,0);} 

QPushButton:hover{background-color:rgba(255,255,255,0.5);} 

QPushButton:pressed{background-color: rgba(100,100,100,1);}; 

2. Prepare each button logo that conforms to your own interface style and add it to QT's material file (. qrc) in advance.

  • --The logo should conform to the interface style and be different from the background color. Because I have many dark interfaces, it is pure white here. If there is no special design, the background of these buttons should be transparent. We can simply draw a desired logo in ps, save it in png format, and then find a converted website on the Internet to convert it to ico format

3. Close the button.

  • If it does not involve modifying the closing interface event, we just need to call QT's default close event under the button clicked slot function we want.

  • --The calling format in QT is:

void MainWindow::on_pushButton_close_clicked() 
{ 
    MainWindow::close();//Close event 
} 
  • --In python, the calling format is closer to the format of signal and slot:
self.pushButton_close.clicked.connect(self.close) 
  • If you need to modify the closing event, for example, in python multiprocess programming, you need to ensure that the main process closes and drives the child processes to close together, you need to modify the contents of closeevent.

  • - the format it calls in QT is as follows:

void MainWindow::closeEvent(QCloseEvent *event) 
{ 

} 
  • The following are called in python:
# Clean up resources when closing the main window 
def closeEvent(self, event): 
    data = "---Visual shield tail clearance measurement system off." 
    ms = Measurement_data_sava(cctv_par.address, data, forma=4, save_lev=1, log_lev=0)       
    kill_name(uwb_par.name_pid) 

4. The maximize (restore) button is implemented, and the minimize button is implemented.

  • --The maximum (restore) button QT is implemented as follows:
void MainWindow::on_pushButton_maximize_clicked() 
{ 
    if (MainWindow::isMaximized()) 
    { 
        MainWindow::showNormal();//Restore event 
        ui->pushButton_maximize->setIcon(QIcon(QPixmap(":/new/new/max.png"))); 
    } 
    else 
    { 
        MainWindow::showMaximized();//Maximize events 
        ui->pushButton_maximize->setIcon(QIcon(QPixmap(":/new/new/back.png"))); 
    } 
} 
  • MainWindow:: ismaxized() can be used to judge the current status of the UI interface to realize the maximization and restoration functions respectively.

  • During function switching, pay attention to changing the sign displayed on the button to display its current real function.

  • --The maximize (restore) button in python is implemented as follows:

# call 
self.pushButton_max .clicked.connect(self.maxornormale) 

# Maximize button function
def maxornormale(self):
    if self.isMaximized():
        self.flgs_max_normal=0
        self.showNormal()
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap(":/newPrefix/resource/icon/max.png"), QtGui.QIcon.Normal,
                        QtGui.QIcon.Off)
        self.pushButton_max.setIcon(icon7)
    else:
        self.flgs_max_normal = 1
        self.showMaximized()
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap(":/newPrefix/resource/icon/back.png"), QtGui.QIcon.Normal,
                        QtGui.QIcon.Off)
        self.pushButton_max.setIcon(icon6)
  • --The minimization button QT is implemented as follows:
void MainWindow::on_pushButton_minimize_clicked() 
{ 
    MainWindow::showMinimized(); 
} 
  • --The minimize button is implemented in python as follows:
self.pushButton_min .clicked.connect(self.showMinimized) 

Realize interface movement

  • Think about it. What is the normal operation process of interface movement? Press and hold the non button position in the title bar with the left mouse button, and then drag the mouse to move the interface from the starting position to the position where the mouse stays. In this process, the parameters that play the role of positioning include the current position of the interface, the starting position of the mouse cursor and the ending position of the mouse cursor. The trigger action is the long press action of the left mouse button.

  • The process is analyzed with the idea of QT programming, which can be expressed as: long press the left mouse button as a signal, the slot function triggered by the signal is to calculate the change of mouse position during operation, and then move the interface according to the change of mouse position to achieve the effect of mouse dragging the interface.

  • Therefore, according to the above analysis, the realization of mouse dragging interface movement requires at least two parts:

    1. Identify the long press action and landing point of the mouse. The long press action is used to trigger the movement operation, and the landing point is used to judge whether the current position should move the interface.
    
    2. According to the recorded mouse position, calculate the change of the mouse in the desktop coordinate system, and then adjust the position of the interface according to the change.
    
  • These actions can be resolved through mouse events.

1. Identify the left mouse button pressing operation through the mouse click event, and record the current position:

  • --The implementation method of this operation in QT is:
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        whereismouse=event->pos();
    }

}
  • --This operation is implemented in python as follows:
# Mouse event, press button
def mousePressEvent(self, e):
    if e.buttons() == QtCore.Qt.LeftButton:
        try:
            self.mos = e.pos()
        except:
            pass

2. Calculate the coordinate change of the mouse cursor through the mouse movement event, and make the interface move the same with the help of the move event.

  • --The implementation method of this operation in QT is:
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::LeftButton)
    {
        if(MainWindow::isMaximized() || MainWindow::isMinimized())
        {
            return;
        }
        else
        {
            if (ui->groupBox_top->underMouse())
            {
                if(ui->groupBox_2->underMouse())
                {

                }
                else
                {
                    MainWindow::move(MainWindow::mapToGlobal(event->pos()-whereismouse));
                }
            }
        }
    }
    event->accept();
}

  • --This operation is implemented in python as follows:
# Mouse movement event
def mouseMoveEvent(self, event):
    if self.pushButton_tip.underMouse():
        pass
    elif self.pushButton_4.underMouse():
        pass
    elif self.pushButton_5.underMouse():
        pass
    else:
        try:
            if event.buttons() == Qt.LeftButton and self.mos:
                self.move(self.mapToGlobal(event.pos() - self.mos))
            event.accept()
        except:
            pass
  • The underMouse() statement can obtain whether the mouse is currently suspended on the corresponding control. Through this statement, you can control the effective range of interface drag so that it is not triggered by mistake in places requiring mouse operation such as buttons.

Posted by trawets on Tue, 02 Nov 2021 02:25:36 -0700