您好,登錄后才能下訂單哦!
Qt實現的窗口樣式默認使用的是當前操作系統的原生窗口樣式,在不同操作系統下原生窗口樣式顯示的風格是不一樣的。
可以為每個Widget設置風格:setStyle(QStyle style)
獲取當前平臺支持的原有QStyle樣式QStyleFactory.keys()
對QApplication設置QStyle樣式QApplication.setStyle(QStyleFactory.create(“WindowsXP”))
如果其它Widget沒有設置QStyle,則默認使用QApplication使用的QStyle。
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())
# 選擇當前窗口風格
index = combo.findText(QApplication.style().objectName(), Qt.MatchFixedString)
# 設置當前窗口風格
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_())
PyQt5使用setWindowFlags(Qt.WindowFlags)函數設置窗口樣式。
Qt的窗口類型如下:
Qt.Widget:默認窗口,由最大化、最小化、關閉按鈕
Qt.Window:普通窗口,有最大化、最小化、關閉按鈕
Qt.Dialog:對話框窗口,有問號和關閉按鈕
Qt.Popup:彈出窗口,窗口無邊框
Qt.ToolTip:提示窗口,窗口無邊框,無任務欄
Qt.SplashScreen:閃屏,窗口無邊框,無任務欄
Qt.SubWindow:子窗口,窗口無按鈕,但有標題欄
Qt自定義的頂層窗口外觀標識:
Qt.MSWindowsFixedSizeDialogHint:窗口無法調整大小
Qt.FrameLessWindowHint:窗口無邊框
Qt.CustomWinodwHint:有邊框但無標題欄和按鈕,不能移動和拖動
Qt.WindowTitleHint:添加一個標題欄和一個關閉按鈕
Qt.WindowSystemMenuHint:添加系統目錄和一個關閉按鈕
Qt.WindowMaximizeButtonHint:激活最大化和關閉按鈕,禁止最小化按鈕
Qt.WindowMinimizeButtonHint:激活最小化和關閉按鈕,禁止最大化按鈕
Qt.WindowMinMaxButtonsHint:激活最大化、最小化和關閉按鈕
Qt.WindowCloseButtonHint:增加一個關閉按鈕
Qt.WindowContextHelpButtonHint:增加問號和關閉按鈕
Qt.WindowStaysOnTopHint:窗口始終處于頂層位置
Qt.WindowStaysOnBottomHint:窗口始終處于底層位置
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_())
自定義一個無邊框、鋪滿整個顯示屏的窗口實現如下:
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):
# 獲取桌面控件
desktop = QApplication.desktop()
# 獲取屏幕可顯示矩形區域
rect = desktop.availableGeometry()
# 設置窗口尺寸
self.setGeometry(rect)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.showMaximized()
sys.exit(app.exec_())
Qt中有四個圖像類,QPixmap、QImage、QPicture、QBitmap。
QPixmap專為繪圖而設計,在繪制圖片時需要QPixmap。
QImage提供了一個與硬件無關的圖像表示函數,可以用于圖片的像素級訪問。
QPicture是繪圖設備類,繼承自QPainter,可以使用QPainter的begin函數在QPicture上繪圖,使用end結束繪圖,使用QPicture的save函數將QPainter使用過的繪圖指令保存到文件中。
QBitmap是一個繼承自QPixmap的便利類,提供了1bit深度的二值圖像的類,提供的單×××像可以用來制作游標QCursor或者畫刷QBrush。
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_())
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
# 將圖形會值在PixMap畫布
painter2 = QPainter(self.pix)
painter2.drawRect(x, y, w, h)
# 將pximap繪制到窗口
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_())
上述代碼中,首先使用painter將圖形繪制在Pixmap上,然后將Pixmap繪制到窗口中。在拖動鼠標繪制矩形的過程中會出現重影,鼠標拖動過程中,屏幕會刷新很多次,paintEvent函數會被執行很多次,每次都會繪制一個矩形。
為了避免重影,可以使用雙緩沖繪制技術。即使用兩塊畫布,pix和tempPix,tempPix作為臨時緩沖區,當拖動鼠標繪制矩形時,將內容先繪制到tempPix上,然后再將tempPix繪制到界面窗口。當釋放鼠標完成矩形繪制時,將tempPix的內容復制到pix緩沖區,最終完成繪制到窗口。
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_())
QSS(Qt Style Sheets),即Qt樣式表,是用來自定義控件外觀的一種機制。QSS語法規則與CSS大體相同,QSS樣式由兩部分組成,選擇器用于指定哪些控件受到影響,聲明用于指定哪些屬性應該在控件上進行設置。聲明部分是一系列的“屬性:值”,使用分號分隔各個不同的屬性值對,使用大括號將所有的聲明包括在內。QPushButton{color:red;}
表示設置QPushButton及其子類所有實例的前景色為紅色,QPushButton表示選擇器,指定所有的QPushButton類及其子類都會受到影響。
可以使用多個選擇器指定相關的聲明,使用逗號將各個選擇器分隔,如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_())
QSS選擇器有如下幾種類型:
1、通配選擇器:*
,匹配所有的控件
2、類型選擇器,如QPushButton,用于匹配所有的類及其子類的實例。
3、屬性選擇器:匹配所有的屬性及屬性值的實例,如QPushButton[name=”okButton”]將匹配所有的name屬性為okButton的按鈕實例。
4、類選擇器:.ClassName,如.QPushButton用于匹配所有的QPushButton實例,但不匹配其子類。
5、ID選擇器:#objectName,如#okButton匹配所有的ID為okButton的控件,ID即為obejctName。
6、后代選擇器:如QDialog QPushButton,匹配所有的QDialog容器中包含的QPushButton,不管是直接的還是間接的。
7、子選擇器:如QDialog > QPushButton,匹配所有的QDialog容器中包含的QPushButton,要求QPushButton的直接父容器是QDialog。
3、QSS子控件
QSS子控件是一種選擇器,通常應用在復雜控件上,如QComboBox,QComboBox有一個矩形的外邊框,右邊有一個下拉箭頭,點擊后會彈出下拉列表。
::drop-down子控件選擇器可以與選擇器組合使用,QComboBox#combo::drop-down{imge:url(dropdown.png)}
表示為指定ID為combo的QComboBox控件的下拉箭頭自定義圖標。
QSS偽狀態選擇器是以:開頭的一個選擇表達式,如:hover,表示當鼠標經過時的狀態。偽狀態選擇器限制了當控件處于某種狀態時才可以使用的QSS規則,偽狀態只能描述一個控件或復合控件的子控件狀態,因此只能放在選擇器的最后面。QComboBox::drop-down:hover{background-color:red;}
QDarkStyleSheet是一個用于PyQt應用的深黑色樣式表。
GitHub:
https://github.com/ColinDuquesnoy/QDarkStyleSheet
窗口背景主要包括背景色和背景圖片。設置窗口背景主要有三種方法:QSS設置窗口背景;QPalette設置窗口背景;paintEvent函數內部使用QPainter繪制窗口背景。
通過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_())
使用QPalette設置窗口背景顏色。
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_())
使用QPalette設置窗口背景圖片時,需要考慮背景圖片的尺寸,當背景圖片的寬度和高度大于窗口的寬度和高度時,背景圖片將會平鋪整個窗口;當背景圖片的寬度和高度小于窗口的寬度和高度時,則加載多個背景圖片。
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_())
在paintEvent函數內部繪制背景色:
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_())
在paintEvent函數內部繪制背景圖片:
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_())
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_())
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_())
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_())
如果窗口是透明的,通過窗口可以看到桌面,要想實現窗口的透明效果,需要設置窗口透明度。透明度取值范圍為0(完全透明)到1(不透明)。
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_())
Qt中,為了降低耦合性,將UI代碼與業務邏輯代碼進行分離,通常會定義QSS文件,編寫各種控件的樣式,最后使用QApplication.setStyleSheet或QWidget.setStyleSheet設置QSS。
通常編寫QSS文件需要加載到qrc資源文件中,然后編寫一個公用類加載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)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。