By default, the windows and widgets we create with PyQt5 are in the default styles, which are not ugly, but they are not aesthetically pleasing either. In fact, in PyQt5, we can have a higher degree of freedom to customize the style of the window and various widgets, by customizing these styles, in order to achieve the purpose of beautifying the graphical interface.
In this post, we'll work through a real-world example of GUI beautification using QSS and PyQt5's configuration properties.
First on the effect:
I. Layout of the interface and arrangement of components
In image interface programming, a good layout helps to control the shape of the interface globally, and in PyQt5, there are many kinds of layouts for us to choose, the more commonly used layouts are the following:
Form Layout: QFormLayout
Grid Layout: QGridLayout
Horizontal layout: QHBoxLayout
Vertical layout: QVBoxLayout
Each layout has its own way of controlling and characterizing the widgets within the layout, here we choose the grid layout as the solution for this GUI layout.
Within the grid layout, two QWidget() widgets are used as a widget for the left menu module and a widget for the right content module. So the code for the most basic structure of this GUI is shown below:
# coding:utf-8 from PyQt5 import QtCore,QtGui,QtWidgets import sys import qtawesome class MainUi(): def __init__(self): super().__init__() self.init_ui() def init_ui(self): (960,700) self.main_widget = () # Create the main window widget self.main_layout = () # Create the grid layout of the main part self.main_widget.setLayout(self.main_layout) # Set the main window widget layout to a grid layout self.left_widget = () # Create left-hand side widgets self.left_widget.setObjectName('left_widget') self.left_layout = () # Create a grid layout layer for the left-hand widget self.left_widget.setLayout(self.left_layout) # Set the left part layout to grid self.right_widget = () # Create the right-hand side widget self.right_widget.setObjectName('right_widget') self.right_layout = () self.right_widget.setLayout(self.right_layout) # Set the right-hand widget layout to grid self.main_layout.addWidget(self.left_widget,0,0,12,2) # Left part in row 0, column 0, occupying 8 rows and 3 columns self.main_layout.addWidget(self.right_widget,0,2,12,10) # Right part in row 0, column 3, occupying 8 rows and 9 columns (self.main_widget) # Setting up the main part of the window def main(): app = () gui = MainUi() () (app.exec_()) if __name__ == '__main__': main()
Running the code presents the graphical interface shown below:
It's empty, so here's how we'll start filling it with widgets.
Left Menu Bar
In the left menu module, continue to use the grid for the layout of the widgets. Add the button widget QPushButton() to the layout of the left menu the buttons for the left menu, the menu column prompts and the minimize and close buttons for the entire window.
In the init_ui() method of the MainUi() class, use the following code to instantiate the creation of the button:
self.left_close = ("") # Close button self.left_visit = ("") # Blank buttons self.left_mini = ("") # Minimize button self.left_label_1 = ("Daily Recommendations") self.left_label_1.setObjectName('left_label') self.left_label_2 = ("My Music") self.left_label_2.setObjectName('left_label') self.left_label_3 = ("Contact and help") self.left_label_3.setObjectName('left_label') self.left_button_1 = (('',color='white'),"Mandarin Pop") self.left_button_1.setObjectName('left_button') self.left_button_2 = (('',color='white'),"Online FM") self.left_button_2.setObjectName('left_button') self.left_button_3 = (('',color='white'),"Hot Music Video") self.left_button_3.setObjectName('left_button') self.left_button_4 = (('',color='white'),"Local Music") self.left_button_4.setObjectName('left_button') self.left_button_5 = (('',color='white'),"Download Management") self.left_button_5.setObjectName('left_button') self.left_button_6 = (('',color='white'),"My Collection.") self.left_button_6.setObjectName('left_button') self.left_button_7 = (('',color='white'),"Feedback suggestions") self.left_button_7.setObjectName('left_button') self.left_button_8 = (('',color='white'),"Follow us.") self.left_button_8.setObjectName('left_button') self.left_button_9 = (('',color='white'),"Problems encountered.") self.left_button_9.setObjectName('left_button') self.left_xxx = (" ")
Here, we use qtawesome, a third-party library, to implement the display of Font Awesome font icons in the buttons. The created button is then added to the grid layout layer of the left widget:
self.left_layout.addWidget(self.left_mini, 0, 0,1,1) self.left_layout.addWidget(self.left_close, 0, 2,1,1) self.left_layout.addWidget(self.left_visit, 0, 1, 1, 1) self.left_layout.addWidget(self.left_label_1,1,0,1,3) self.left_layout.addWidget(self.left_button_1, 2, 0,1,3) self.left_layout.addWidget(self.left_button_2, 3, 0,1,3) self.left_layout.addWidget(self.left_button_3, 4, 0,1,3) self.left_layout.addWidget(self.left_label_2, 5, 0,1,3) self.left_layout.addWidget(self.left_button_4, 6, 0,1,3) self.left_layout.addWidget(self.left_button_5, 7, 0,1,3) self.left_layout.addWidget(self.left_button_6, 8, 0,1,3) self.left_layout.addWidget(self.left_label_3, 9, 0,1,3) self.left_layout.addWidget(self.left_button_7, 10, 0,1,3) self.left_layout.addWidget(self.left_button_8, 11, 0,1,3) self.left_layout.addWidget(self.left_button_9, 12, 0, 1, 3)
Continuing to run the program code, the graphical interface presented is shown below:
It's ugly, but the basic model is shown, so let's not embellish it here and build the complete structure first. Here is the start of the construction of the right side parts.
Right Content Module
In the right-hand content module, there are several main content modules as follows:
Search Module
Recommended Music Module
Music List Module
Music Song List Module
Music Playback Progress Module
Music Playback Control Module
In the search module, there is a text and a search box, we through the QLable() widget and QLineEdit() widget to realize, these two parts at the same time wrapped in a grid layout of the QWidget () widget, divided into the first column and the second column of the code is shown below:
self.right_bar_widget = () # Right top search box widget self.right_bar_layout = () # Right top search box grid layout self.right_bar_widget.setLayout(self.right_bar_layout) self.search_icon = (chr(0xf002) + ' '+'Search ') self.search_icon.setFont(('fa', 16)) self.right_bar_widget_search_input = () self.right_bar_widget_search_input.setPlaceholderText("Type in artist, song or user and enter to search.") self.right_bar_layout.addWidget(self.search_icon,0,0,1,1) self.right_bar_layout.addWidget(self.right_bar_widget_search_input,0,1,1,8) self.right_layout.addWidget(self.right_bar_widget, 0, 0, 1, 9)
Running the program code, the graphical interface it presents is shown below:
Then there is the Recommended Music module, where there is a recommended title, and a horizontally arranged list of music covers here:
Recommended titles are implemented using QLable();
The list of music covers consists of multiple QToolButton(), which continues to be contained by a QWidget() widget with a QGridLayout() layout.
So, its code is:
self.right_recommend_label = ("Recommendation of the Day") self.right_recommend_label.setObjectName('right_lable') self.right_recommend_widget = () # Recommended Cover Widgets self.right_recommend_layout = () # Recommended Cover Grid Layout self.right_recommend_widget.setLayout(self.right_recommend_layout) self.recommend_button_1 = () self.recommend_button_1.setText("Cozy HANM.") # Set button text self.recommend_button_1.setIcon(('./')) # Set button icons self.recommend_button_1.setIconSize((100,100)) # Set icon size self.recommend_button_1.setToolButtonStyle() # Setup button in the form of the figure above below self.recommend_button_2 = () self.recommend_button_2.setText("That song.") self.recommend_button_2.setIcon(('./')) self.recommend_button_2.setIconSize((100, 100)) self.recommend_button_2.setToolButtonStyle() self.recommend_button_3 = () self.recommend_button_3.setText("The Great Smallness.") self.recommend_button_3.setIcon(('./')) self.recommend_button_3.setIconSize((100, 100)) self.recommend_button_3.setToolButtonStyle() self.recommend_button_4 = () self.recommend_button_4.setText("The Quest for Glory.") self.recommend_button_4.setIcon(('./')) self.recommend_button_4.setIconSize((100, 100)) self.recommend_button_4.setToolButtonStyle() self.recommend_button_5 = () self.recommend_button_5.setText("Hunt for the Occasion Series.") self.recommend_button_5.setIcon(('./')) self.recommend_button_5.setIconSize((100, 100)) self.recommend_button_5.setToolButtonStyle() self.right_recommend_layout.addWidget(self.recommend_button_1,0,0) self.right_recommend_layout.addWidget(self.recommend_button_2,0,1) self.right_recommend_layout.addWidget(self.recommend_button_3, 0, 2) self.right_recommend_layout.addWidget(self.recommend_button_4, 0, 3) self.right_recommend_layout.addWidget(self.recommend_button_5, 0, 4) self.right_layout.addWidget(self.right_recommend_label, 1, 0, 1, 9) self.right_layout.addWidget(self.right_recommend_widget, 2, 0, 2, 9)
Continuing to run the program code, the resulting graphical interface is shown below:
Next, create the Music List module and the Music Song List module. Both the Music List module and the Music Song List module have a title and a widget to hold specific content.
We use QLabel() widget for the title, QPushButton() widget for the music list, and QToolButton() widget for the music list.
The specific code for the music list is shown below:
self.right_newsong_lable = ("Latest Songs") self.right_newsong_lable.setObjectName('right_lable') self.right_playlist_lable = ("Hit List.") self.right_playlist_lable.setObjectName('right_lable') self.right_newsong_widget = () # Latest song parts self.right_newsong_layout = () # Latest song widget grid layout self.right_newsong_widget.setLayout(self.right_newsong_layout) self.newsong_button_1 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.newsong_button_2 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.newsong_button_3 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.newsong_button_4 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.newsong_button_5 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.newsong_button_6 = ("Night Machine Vivienne Chen Friends Forever 03::29") self.right_newsong_layout.addWidget(self.newsong_button_1,0,1,) self.right_newsong_layout.addWidget(self.newsong_button_2, 1, 1, ) self.right_newsong_layout.addWidget(self.newsong_button_3, 2, 1, ) self.right_newsong_layout.addWidget(self.newsong_button_4, 3, 1, ) self.right_newsong_layout.addWidget(self.newsong_button_5, 4, 1, ) self.right_newsong_layout.addWidget(self.newsong_button_6, 5, 1, )
The code for the Music Song List module is shown below:
self.right_playlist_widget = () # Play song list widget self.right_playlist_layout = () # Play Song List Grid Layout self.right_playlist_widget.setLayout(self.right_playlist_layout) self.playlist_button_1 = () self.playlist_button_1.setText("Can't get over the all-day loop music...") self.playlist_button_1.setIcon(('./')) self.playlist_button_1.setIconSize((100, 100)) self.playlist_button_1.setToolButtonStyle() self.playlist_button_2 = () self.playlist_button_2.setText("You don't need lyrics to move your heart.") self.playlist_button_2.setIcon(('./')) self.playlist_button_2.setIconSize((100, 100)) self.playlist_button_2.setToolButtonStyle() self.playlist_button_3 = () self.playlist_button_3.setText("Those you know well and don't know the names of...") self.playlist_button_3.setIcon(('./')) self.playlist_button_3.setIconSize((100, 100)) self.playlist_button_3.setToolButtonStyle() self.playlist_button_4 = () self.playlist_button_4.setText("Those English songs that are poisoned just by the intro.") self.playlist_button_4.setIcon(('./')) self.playlist_button_4.setIconSize((100, 100)) self.playlist_button_4.setToolButtonStyle() self.right_playlist_layout.addWidget(self.playlist_button_1,0,0) self.right_playlist_layout.addWidget(self.playlist_button_2, 0, 1) self.right_playlist_layout.addWidget(self.playlist_button_3, 1, 0) self.right_playlist_layout.addWidget(self.playlist_button_4, 1, 1)
Then add them to the right layout layer:
self.right_layout.addWidget(self.right_newsong_lable, 4, 0, 1, 5) self.right_layout.addWidget(self.right_playlist_lable, 4, 5, 1, 4) self.right_layout.addWidget(self.right_newsong_widget, 5, 0, 1, 5) self.right_layout.addWidget(self.right_playlist_widget, 5, 5, 1, 4)
Continuing to run the program code, the graphical interface is displayed as shown below:
This way, you can basically see what the graphical interface will look like, with the final music playback progress bar and music playback control button set still to come.
The music playback progress bar is implemented using the QProgressBar() progress bar widget, and the music playback control button group is implemented using a QWidget() widget wrapped with three QPushButton() button widgets.
Its specific code is as follows:
self.right_process_bar = () # Play progress widget self.right_process_bar.setValue(49) self.right_process_bar.setFixedHeight(3) # Set the height of the progress bar self.right_process_bar.setTextVisible(False) # Do not show progress bar text self.right_playconsole_widget = () # Playback control components self.right_playconsole_layout = () # Playback control widget grid layout layer self.right_playconsole_widget.setLayout(self.right_playconsole_layout) self.console_button_1 = (('', color='#F76677'), "") self.console_button_2 = (('', color='#F76677'), "") self.console_button_3 = (('', color='#F76677', font=18), "") self.console_button_3.setIconSize((30, 30)) self.right_playconsole_layout.addWidget(self.console_button_1, 0, 0) self.right_playconsole_layout.addWidget(self.console_button_2, 0, 2) self.right_playconsole_layout.addWidget(self.console_button_3, 0, 1) self.right_playconsole_layout.setAlignment() # Set layout widgets to be centered self.right_layout.addWidget(self.right_process_bar, 9, 0, 1, 9) self.right_layout.addWidget(self.right_playconsole_widget, 10, 0, 1, 9)
Finally running the program code, we get the form of the complete part of this graphical interface, which is shown in the following figure:
After completing the construction of the basic GUI widgets, next, we can beautify this GUI a little bit, because this current look is really ugly and unattractive.
Second, the use of QSS and widget properties to beautify the window components
QSS known as Qt StyleSheet, is used to control the style sheet of QT controls. And its Web development in the front part of the CSS style sheet is similar to the next, we will create a good graphical interface through the QSS to beautify the above.
Window control buttons
Start with the menu bar on the left.
At the very top of the left side are three window control buttons, which we need to set in the form of dots. First, we use the setFixedSize() method of QPushButton() to set the size of the buttons:
self.left_close.setFixedSize(15,15) # Set the size of the close button self.left_visit.setFixedSize(15, 15) # Set button size self.left_mini.setFixedSize(15, 15) # Setting the Minimize Button Size
Then, through the setStyleSheet() method, set the QSS style of the button widgets. Here, the left button defaults to light green, and dark green when the mouse is hovered; the center button defaults to light yellow, and dark yellow when the mouse is hovered; and the right button defaults to light red, and red when the mouse is hovered. So their QSS style settings are shown below:
self.left_close.setStyleSheet('''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''') self.left_visit.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''') self.left_mini.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')
Run the program code, you can find that the three control buttons have been turned into more beautiful dots:
Left menu button
Since the background of the left widget is gray in the final GUI, we need to set the buttons and text color in the left menu to white and remove the borders of the buttons and set the qss style in left_widget to:
self.left_widget.setStyleSheet(''' QPushButton{border:none;color:white;} QPushButton#left_label{ border:none; border-bottom:1px solid white; font-size:18px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } QPushButton#left_button:hover{border-left:4px solid red;font-weight:700;} ''')
Right background, search box and module text
After completing the beautification of the left side of the components, we proceed to the right side of the content components to deal with, first of all, the top of the search box, because the search box is using the QLineEdit () widget, by default, the sharp corners are very unattractive, we rounded corners of its processing:
self.right_bar_widget_search_input.setStyleSheet( '''QLineEdit{ border:1px solid gray; width:300px; border-radius:10px; padding:2px 4px; }''')
Since the graphical interface will show rounded corners without borders, the upper and lower right corners of the right side widgets need to be processed as rounded corners first, and the background is set to white. We also need to enlarge the fonts of the titles of the Recommendation module, Music List module and Music Song List module, so the final style is:
self.right_widget.setStyleSheet(''' QWidget#right_widget{ color:#232C51; background:white; border-top:1px solid darkGray; border-bottom:1px solid darkGray; border-right:1px solid darkGray; border-top-right-radius:10px; border-bottom-right-radius:10px; } QLabel#right_lable{ border:none; font-size:16px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } ''')
Running the program code presents a graphical interface that already looks more and more like the final form:
Recommendation Module, Song List Module and Song List Module
Since the QToolButton() widget is used in both the Recommendations module and the Song List module, their styles are similar:
self.right_recommend_widget.setStyleSheet( ''' QToolButton{border:none;} QToolButton:hover{border-bottom:2px solid #F76677;} ''') self.right_playlist_widget.setStyleSheet( ''' QToolButton{border:none;} QToolButton:hover{border-bottom:2px solid #F76677;} ''')
And the music list uses the QPushButton() button widget, for which we need to remove the borders, change the font and color, etc., so it is styled as:
self.right_newsong_widget.setStyleSheet(''' QPushButton{ border:none; color:gray; font-size:12px; height:40px; padding-left:5px; padding-right:10px; text-align:left; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''')
Run the program code and the graphical interface is now shown below:
Playback progress bar and playback control button groups
Next it's the turn of the play progress bar and playback control buttons group, we need to set the sample color of the play progress bar to light red, and then remove the border of the playback control buttons, so its QSS style is:
self.right_process_bar.setStyleSheet(''' QProgressBar::chunk { background-color: #F76677; } ''') self.right_playconsole_widget.setStyleSheet(''' QPushButton{ border:none; } ''')
By this point, the graphical interface that appears when you run the program code is looking more and more like the final interface:
Next comes the final touches of landscaping!
Third, the window to achieve borderless and rounded corners
Having reached the previous step, we are basically done with the styles adjusted through QSS, and now need to use the other built-in properties of the various components in PyQt5 to complete the final beautification of this GUI.
Set window background transparency
Transparent window background will make the graphical interface modern and stylish, we come to say that the graphical interface window background is set to transparent:
(0.9) # Set window transparency (.WA_TranslucentBackground) # Set window background transparency
Running the program code, we get an interface with a very different look and feel:
Remove window borders
Window background set to transparent experience is very different, but the default border is very inconsistent, then remove the ugly default border is necessary to do the work, through the window of the setWindowFlag () attribute we can set the state of the window so that the border to hide:
() # Hide the border
In order to avoid the left widget not having a background color and border to display after hiding the window border, we then add the QSS property to the left widget:
self.main_widget.setStyleSheet(''' QWidget#left_widget{ background:gray; border-top:1px solid white; border-bottom:1px solid white; border-left:1px solid white; border-top-left-radius:10px; border-bottom-left-radius:10px; } ''')
Run the program code and a 99% complete graphical interface comes out:
The reason why it is 99% complete is because it can be noticed that there is a gap between the left part and the right part in the graphical interface, and we got rid of that gap by setting the gap of the inner parts of the layout:
self.main_layout.setSpacing(0)
This appears as a graphical interface without that obtrusive gap:
Thus, our beautification of the GUI is complete.
This article introduces the PyQt5 beautification of forms and controls on the example of the end of the speech, more on the use of python in the GUI library graphical interface development library PyQt5 to beautify the form and controls (shaped form) examples, please see the following related links