PyQt5 Quick Start (VI) GUI Interface Design of PyQt5
I. Window Style
1. Setting Window Style
The default window style implemented by Qt is the native window style of the current operating system, and the display style of the native window style is different under different operating systems.
Styles can be set for each Widget:
setStyle(QStyle style)
Getting the original QStyle style supported by the current platform
QStyleFactory.keys()
Setting QStyle Style for Q Application
QApplication.setStyle(QStyleFactory.create("WindowsXP"))
If QStyle is not set by other widgets, the QStyle used by QApplication is used by default.
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.layout = QHBoxLayout() label = QLabel("Set Style:",self) combo = QComboBox(self) combo.addItems(QStyleFactory.keys()) # Select the current window style index = combo.findText(QApplication.style().objectName(), Qt.MatchFixedString) # Setting the current window style combo.setCurrentIndex(index) combo.activated[str].connect(self.onCurrentIndexChanged) self.layout.addWidget(label) self.layout.addWidget(combo) self.setLayout(self.layout) self.setWindowTitle("Application Style") self.resize(300, 100) def onCurrentIndexChanged(self, style): QApplication.setStyle(style) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
2. Setting Window Style
PyQt5 uses the setWindows Flags (Qt. Windows Flags) function to set the window style.
The window types of Qt are as follows:
Qt.Widget: Default window, by maximizing, minimizing, closing buttons
Qt.Window: Ordinary window with maximization, minimization and closure buttons
Qt.Dialog: Dialog window with question mark and close button
Qt.Popup: Pop-up window with no borders
Qt.ToolTip: Tip window, no borders, no taskbar
Qt.SplashScreen: Flash screen, window without borders, taskbar
Qt.SubWindow: Subwindow, no button, but with title bar
Qt Customized Top Window Appearance Logo:
Qt.MS Windows Fixed Size Dialog Hint: Windows cannot be resized
Qt. FrameLess Windows Hint: Window without Borders
Qt. Custom WinodwHint: Borders but no title bars and buttons, unable to move and drag
Qt. Windows TitleHint: Add a title bar and a close button
Qt. Windows System MenuHint: Add System Directory and a Close Button
Qt. Windows MaximizeButtonHint: Activate the MaximizeButton and Close Button, Disable the Minimization Button
Qt. Windows Minimize Button Hint: Activate Minimize and Close Buttons, Disable Maximize Buttons
Qt. Windows MinMax Buttons Hint: Activate the Maximization, Minimization and Close buttons
Qt. Windows Close Button Hint: Add a Close button
Qt. Windows Context Help Button Hint: Add Question Mark and Close Button
Qt. Windows Stays On TopHint: Windows are always at the top
Qt. Windows Stays On Bottom Hint: Windows are always at the bottom
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint) self.resize(400, 200) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3. Custom Window
Customize a window that has no border and is covered with the whole display screen as follows:
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint) self.setStyleSheet("background-color:blue;") def showMaximized(self): # Get desktop controls desktop = QApplication.desktop() # Get the screen to display rectangular areas rect = desktop.availableGeometry() # Setting window size self.setGeometry(rect) self.show() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.showMaximized() sys.exit(app.exec_())
Drawing
1. Image class
There are four image classes in Qt, QPixmap, QImage, QPicture and QBitmap.
QPixmap is designed for drawing, and QPixmap is needed for drawing pictures.
QImage provides a hardware-independent image representation function that can be used for pixel-level access to images.
QPicture is a drawing device class, inherited from QPainter. It can use QPainter's begin function to draw on QPicture, end the drawing with end, and save the drawing instructions used by QPainter to file with QPicture's save function.
QBitmap is a convenience class inherited from QPixmap, which provides a binary image of 1 bit depth. The single * image can be used to make cursor QCursor or brush QBrush.
2. Drawing
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.pix = QPixmap(400, 400) self.pix.fill(Qt.white) self.lastPoint = QPoint() self.endPoint = QPoint() self.setWindowFlags(Qt.WindowTitleHint) self.resize(400, 400) def paintEvent(self, event): painter = QPainter(self.pix) painter.drawLine(self.lastPoint, self.endPoint) self.lastPoint = self.endPoint painter = QPainter(self) painter.drawPixmap(0, 0, self.pix) def mouseMoveEvent(self, event): if event.buttons() and Qt.LeftButton: self.endPoint = event.pos() self.update() def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.lastPoint = event.pos() self.endPoint = self.lastPoint def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.endPoint = event.pos() self.update() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3. Double Buffer Drawing
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.pix = QPixmap(400, 400) self.pix.fill(Qt.white) self.lastPoint = QPoint() self.endPoint = QPoint() self.setWindowFlags(Qt.WindowTitleHint) self.resize(400, 400) def paintEvent(self, event): painter1 = QPainter(self) x = self.lastPoint.x() y = self.lastPoint.y() w = self.endPoint.x() - x h = self.endPoint.y() - y # Value the graphics on the PixMap canvas painter2 = QPainter(self.pix) painter2.drawRect(x, y, w, h) # Draw pximap to a window painter1.drawPixmap(0, 0, self.pix) def mouseMoveEvent(self, event): if event.buttons() and Qt.LeftButton: self.endPoint = event.pos() self.update() def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.lastPoint = event.pos() self.endPoint = self.lastPoint def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.endPoint = event.pos() self.update() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
In the above code, first the graphics are drawn on Pixmap using painter, and then the Pixmap is drawn into the window. In the process of dragging the mouse to draw a rectangle, there will be a double shadow. In the process of dragging the mouse, the screen will be refreshed many times. The paintEvent function will be executed many times, and a rectangle will be drawn each time.
To avoid duplication, double buffer rendering technique can be used. Even using two canvas, pix and tempPix, tempPix as temporary buffer, when dragging the mouse to draw a rectangle, the content is drawn to tempPix first, and then tempPix to the interface window. When the mouse is released to complete rectangular drawing, the content of tempPix is copied to the pix buffer, and finally the drawing is completed to the window.
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.pix = QPixmap(400, 400) self.pix.fill(Qt.white) self.lastPoint = QPoint() self.endPoint = QPoint() self.setWindowFlags(Qt.WindowTitleHint) self.resize(400, 400) self.isDrawing = False self.tempPix = QPixmap() def paintEvent(self, event): painter = QPainter(self) x = self.lastPoint.x() y = self.lastPoint.y() w = self.endPoint.x() - x h = self.endPoint.y() - y if self.isDrawing: self.tempPix = self.pix pp = QPainter(self.tempPix) pp.drawRect(x, y, w, h) painter.drawPixmap(0, 0, self.tempPix) else: pp = QPainter(self.pix) pp.drawRect(x, y, w, h) painter.drawPixmap(0, 0, self.pix) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.lastPoint = event.pos() self.endPoint = self.lastPoint self.isDrawing = True def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.endPoint = event.pos() self.update() self.isDrawing = False if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3. QSS Style Settings
1. QSS grammar rules
QSS (Qt Style Sheets), or Qt style sheets, is a mechanism for customizing the appearance of controls. QSS grammar rules are basically the same as CSS. The QSS style consists of two parts. The selector is used to specify which controls are affected, and the declaration is used to specify which properties should be set on the controls. The declaration part is a series of "attributes: values", using semicolons to separate different attribute value pairs and braces to include all declarations.
QPushButton{color:red;}
Represents setting the foreground color of all instances of QPushButton and its subclasses to red, QPushButton represents a selector, and specifying that all QPushButton classes and their subclasses will be affected.
Multiple selectors can be used to specify relevant declarations, and commas can be used to separate selectors, such as QPushButton,QLineEdit{color:red;}
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) button = QPushButton("Button") self.layout = QHBoxLayout() self.layout.addWidget(button) self.setLayout(self.layout) qss = "QPushButton{color:red;}" self.setStyleSheet(qss) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
2. QSS selector type
There are several types of QSS selectors:
1. Wildcard selector: *, matching all controls
2. Type selectors, such as QPushButton, are used to match instances of all classes and their subclasses.
3. Attribute selector: instances that match all attributes and attribute values, such as QPushButton[name="okButton"] will match all button instances whose name attribute is okButton.
4. Class selector:. ClassName, such as. QPushButton, is used to match all instances of QPushButton, but not its subclasses.
5. ID selector: objectName, for example, okButton matches all controls whose ID is okButton, and the ID is obejctName.
6. Progeny selectors, such as QDialog QPushButton, match QPushButton contained in all QDialog containers, whether direct or indirect.
7. Child selectors: such as QDialog > QPushButton, match all QPushButton contained in the QDialog container, requiring the direct parent container of QPushButton to be QDialog.
3. QSS child control
QSS sub-control is a selector, which is usually applied to complex controls, such as QComboBox. QComboBox has a rectangular outer border and a drop-down arrow on the right. When clicked, a drop-down list pops up.
:: drop-down child control selector can be used in combination with selector.
QComboBox combo:: drop-down {imge: URL (dropdown. png)} is a drop-down arrow custom icon for a QComboBox control with a combo ID.
4. QSS pseudo-state
QSS pseudo-state selector is a selection expression that starts with: hover, which represents the state when the mouse passes by. Pseudo-state selector limits the QSS rules that can be used when a control is in a certain state. Pseudo-state can only describe the state of a control or a composite control's sub-control, so it can only be placed at the end of the selector.
QComboBox::drop-down:hover{background-color:red;}
5,QDarkStyleSheet
QDark Style Sheet is a dark black stylesheet for PyQt applications.
GitHub:
https://github.com/ColinDuquesnoy/QDarkStyleSheet
IV. Setting Window Background
The window background mainly includes background color and background picture. There are three main ways to set the window background: QSS setting the window background; QPalette setting the window background; paintEvent function using QPainter to draw the window background.
1. QSS Setting Window Background
The background color or background image of the window can be set by QSS.
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setObjectName("mainWindow") qss = "QWidget#mainWindow{background-color:black;}" # qss = "QWidget#mainWindow{border-image:url(background.png);}" self.setStyleSheet(qss) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
2. QPalette Setting Window Background
Use QPalette to set the background color of the window.
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) palette = QPalette() palette.setColor(QPalette.Background, Qt.black) self.setPalette(palette) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
When using QPalette to set the window background picture, we need to consider the size of the background picture. When the width and height of the background picture are larger than the width and height of the window, the background picture will flatten the whole window. When the width and height of the background picture are smaller than the width and height of the window, multiple background pictures will be loaded.
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) palette = QPalette() palette.setBrush(QPalette.Background, QBrush(QPixmap("background.png"))) self.setPalette(palette) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3. Paint Event Draws Window Background
Draw the background color inside the paintEvent function:
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") def paintEvent(self, event): painter = QPainter(self) painter.setBrush(Qt.black) painter.drawRect(self.rect()) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
Draw the background picture inside the paintEvent function:
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") def paintEvent(self, event): painter = QPainter(self) pixmap = QPixmap("background.png") painter.drawPixmap(self.rect(), pixmap) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
5. Examples of Style Settings
1. Add background pictures to labels
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.layout = QVBoxLayout() label = QLabel() label.setStyleSheet("QLabel{border-image:url(background.png);}") label.setFixedHeight(400) label.setFixedWidth(600) self.layout.addWidget(label) self.setLayout(self.layout) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
2. Adding Background Pictures to Buttons
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.layout = QVBoxLayout() button = QPushButton("Button") button.setMaximumSize(60, 30) button.setObjectName("okButton") button.setStyleSheet("QPushButton#okButton{border-image:url(background.png);}") self.layout.addWidget(button) self.setLayout(self.layout) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3. Scaling Pictures
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.layout = QVBoxLayout() label = QLabel() img = QImage("background.png") result = img.scaled(label.width(), label.height(),Qt.IgnoreAspectRatio, Qt.SmoothTransformation) label.setPixmap(QPixmap.fromImage(result)) self.layout.addWidget(label) self.setLayout(self.layout) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
4. Setting window transparency
If the window is transparent, you can see the desktop through the window. To achieve the transparent effect of the window, you need to set the transparency of the window. Transparency ranges from 0 (completely transparent) to 1 (opaque).
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow") self.setWindowOpacity(0.5) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
5. Loading QSS
In Qt, in order to reduce coupling and separate UI code from business logic code, QSS files are usually defined, various control styles are written, and QApplication. setStyle Sheet or QWidget. setStyle Sheet are used to set QSS.
Typically, writing QSS files requires loading into qrc resource files, and then writing a common class to load QSS.
class CommonHelper(object): @staticmethod def setStyleSheet(filename): if filename is not None: style = "" with open(filename, "r") as f: style = f.read() qApp.setStyleSheet(style)