设置窗口风格
'''
窗口、绘图与特效:设置窗口风格
设置窗口中控件的风格
QApplication.setStyle(...)
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtCore
from PyQt5.QtGui import *
class WindowStyle(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('设置窗口风格')
horizontalLayout = QHBoxLayout()
self.styleLabel = QLabel('设置窗口风格:')
self.styleComboBox = QComboBox()
self.styleComboBox.addItems(QStyleFactory.keys())
# 获取当前窗口的风格
print(QApplication.style().objectName())
index = self.styleComboBox.findText(QApplication.style().objectName(),QtCore.Qt.MatchFixedString)
self.styleComboBox.setCurrentIndex(index)
self.styleComboBox.activated[str].connect(self.handleStyleChanged)
horizontalLayout.addWidget(self.styleLabel)
horizontalLayout.addWidget(self.styleComboBox)
self.setLayout(horizontalLayout)
def handleStyleChanged(self,style):
QApplication.setStyle(style)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = WindowStyle()
form.show()
sys.exit(app.exec_())
设置窗口样式(主要是窗口边框、标题栏以及窗口本身的样式)
'''
设置窗口样式(主要是窗口边框、标题栏以及窗口本身的样式)
'''
from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
class WindowPattern(QMainWindow):
def __init__(self):
super().__init__()
self.resize(500,260)
self.setWindowTitle('设置窗口的样式')
self.setWindowFlags(Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint )
self.setObjectName("MainWindow")
self.setStyleSheet("#MainWindow{border-image:url(images/python.jpg);}")
if __name__ == "__main__":
app = QApplication(sys.argv)
form = WindowPattern()
form.show()
sys.exit(app.exec_())
用代码控制窗口的最大化和最小化
'''
用代码控制窗口的最大化和最小化
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
### 自定义窗口类
class WindowMaxMin(QWidget):
### 构造函数
def __init__(self, parent=None):
'''构造函数'''
# 调用父类构造函数
super(WindowMaxMin, self).__init__(parent)
self.resize(300,400)
self.setWindowTitle("用代码控制窗口的最大化和最小化")
self.setWindowFlags(Qt.WindowMaximizeButtonHint)
layout = QVBoxLayout()
maxButton1 = QPushButton()
maxButton1.setText('窗口最大化1')
maxButton1.clicked.connect(self.maximized1)
maxButton2 = QPushButton()
maxButton2.setText('窗口最大化2')
maxButton2.clicked.connect(self.showMaximized)
minButton = QPushButton()
minButton.setText('窗口最小化')
minButton.clicked.connect(self.showMinimized)
layout.addWidget(maxButton1)
layout.addWidget(maxButton2)
layout.addWidget(minButton)
self.setLayout(layout)
def maximized1(self):
desktop = QApplication.desktop()
# 获取桌面可用尺寸
rect = desktop.availableGeometry()
self.setGeometry(rect)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = WindowMaxMin()
window.show()
# 应用程序事件循环
sys.exit(app.exec_())
项目实战:实现绘图应用
'''
项目实战:实现绘图应用
需要解决3个核心内容
1. 如何绘图
在paintEvent方法中绘图,通过调用update方法触发painEvent的调用
2. 在哪里绘图
在白色背景的QPixmap对象中绘图
3. 如何通过移动鼠标进行绘图
鼠标拥有3个事件:
(1)鼠标按下:mousePressEvent
(2)鼠标移动:mouseMoveEvent
(3)鼠标抬起:mouseReleaseEvent
'''
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QPixmap
from PyQt5.QtCore import Qt, QPoint
class Drawing(QWidget):
def __init__(self, parent=None):
super(Drawing, self).__init__(parent)
self.setWindowTitle("绘图应用")
self.pix = QPixmap()
self.lastPoint = QPoint()
self.endPoint = QPoint()
self.initUi()
def initUi(self):
self.resize(600, 600)
# 画布大小为400*400,背景为白色
self.pix = QPixmap(600, 600)
self.pix.fill(Qt.white)
def paintEvent(self, event):
pp = QPainter(self.pix)
# 根据鼠标指针前后两个位置绘制直线
pp.drawLine(self.lastPoint, self.endPoint)
# 让前一个坐标值等于后一个坐标值,
# 这样就能实现画出连续的线
self.lastPoint = self.endPoint
painter = QPainter(self)
painter.drawPixmap(0, 0, self.pix)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.lastPoint = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() and Qt.LeftButton:
self.endPoint = event.pos()
self.update()
def mouseReleaseEvent(self, event):
# 鼠标左键释放
if event.button() == Qt.LeftButton:
self.endPoint = event.pos()
# 进行重新绘制
self.update()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Drawing()
form.show()
sys.exit(app.exec_())
QSS基础
'''
QSS基础
QSS(Qt Style Sheets)
Qt样式表
用于设置控件的样式
CSS
'''
from PyQt5.QtWidgets import *
import sys
class BasicQSS(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QSS样式")
btn1 = QPushButton(self)
btn1.setText("按钮1")
btn2 = QPushButton(self)
btn2.setText("按钮2")
btn3 = QPushButton(self)
btn3.setText("按钮3")
vbox = QVBoxLayout()
vbox.addWidget(btn1)
vbox.addWidget(btn2)
vbox.addWidget(btn3)
self.setLayout(vbox)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = BasicQSS()
# 选择器
qssStyle = '''
QPushButton {
background-color:red
}
'''
form.setStyleSheet(qssStyle)
form.show()
sys.exit(app.exec_())
QDarkStyleSheet样式
'''
使用QSS选择器设置控件样式
'''
from PyQt5.QtWidgets import *
import sys
import qdarkstyle
class QSSSelector(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QSS样式")
btn1 = QPushButton(self)
btn1.setText("按钮1")
btn2 = QPushButton(self)
btn2.setProperty('name','btn2')
btn2.setText("按钮2")
btn3 = QPushButton(self)
btn3.setProperty('name','btn3')
btn3.setText("按钮3")
vbox = QVBoxLayout()
vbox.addWidget(btn1)
vbox.addWidget(btn2)
vbox.addWidget(btn3)
self.setLayout(vbox)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = QSSSelector()
# 选择器
qssStyle = '''
QPushButton[name="btn2"] {
background-color:red;
color:yellow;
height:120;
font-size:60px;
}
QPushButton[name="btn3"] {
background-color:blue;
color:yellow;
height:60;
font-size:30px;
}
'''
#form.setStyleSheet(qssStyle)
form.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
form.show()
sys.exit(app.exec_())
QSS子控件选择器
'''
QSS子控件选择器
QComboBox
'''
from PyQt5.QtWidgets import *
import sys
class QSSSubControl(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QSS子控件选择器")
combo = QComboBox(self)
combo.setObjectName("myComboBox")
combo.addItem("Window")
combo.addItem("Linux")
combo.addItem("Mac OS X")
combo.move(50,50)
self.setGeometry(250,200,320,150)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = QSSSubControl()
qssStyle = '''
QComboBox#myComboBox::drop-down {
image:url(./images/dropdown.png)
}
'''
form.setStyleSheet(qssStyle)
form.show()
sys.exit(app.exec_())
设置背景色和背景图-QSS、QPalette
'''
使用多种方式设置窗口背景色和背景图片
1. QSS
2. QPalette
3. 直接绘制
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
app = QApplication(sys.argv)
win = QMainWindow()
win.setWindowTitle("背景图片")
win.resize(350,250)
win.setObjectName("MainWindow")
'''
# 通过QSS动态修改窗口的背景颜色和背景图片
win.setStyleSheet("#MainWindow{border-image:url(./images/python.jpg);}")
win.setStyleSheet("#MainWindow{background-color:yellow}")
'''
win.setStyleSheet("#MainWindow{border-image:url(./images/python.jpg);}")
# 通过QPalette设置背景图片和背景颜色
#palette = QPalette()
#palette.setBrush(QPalette.Background,QBrush(QPixmap("./images/python.jpg")))
#palette.setColor(QPalette.Background,Qt.red)
#win.setPalette(palette)
win.show()
sys.exit(app.exec())
设置背景色和背景图-直接绘制
'''
使用多种方式设置窗口背景色和背景图片
1. QSS
2. QPalette
3. 直接绘制
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Background2(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("绘制背景图片")
def paintEvent(self, event):
painter = QPainter(self)
pixmap = QPixmap('./images/screen1.jpg')
painter.drawPixmap(self.rect(),pixmap)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Background2()
form.show()
sys.exit(app.exec_())
实现不规则窗口(异形窗口)
'''
实现不规则窗口(异形窗口)
通过mask实现异形窗口
需要一张透明的png图,透明部分被扣出,形成一个非矩形的区域
移动和关闭不规则窗口
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class AbnormityWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("异形窗口")
self.pix = QBitmap('./images/mask.png')
self.resize(self.pix.size())
self.setMask(self.pix)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.m_drag = True
self.m_DragPosition = event.globalPos() - self.pos()
self.setCursor(QCursor(Qt.OpenHandCursor))
print(event.globalPos()) #
print(event.pos())
print(self.pos())
if event.button() == Qt.RightButton:
self.close()
def mouseMoveEvent(self, QMouseEvent):
if Qt.LeftButton and self.m_drag:
# 当左键移动窗体修改偏移值
# QPoint
# 实时计算窗口左上角坐标
self.move(QMouseEvent.globalPos() - self.m_DragPosition)
def mouseReleaseEvent(self, QMouseEvent):
self.m_drag = False
self.setCursor(QCursor(Qt.ArrowCursor))
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),QPixmap('./images/screen1.jpg'))
if __name__ == "__main__":
app = QApplication(sys.argv)
form = AbnormityWindow()
form.show()
sys.exit(app.exec_())
窗体的动画实现
'''
不规则窗体的动画实现
'''
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPixmap, QPainter, QCursor
from PyQt5.QtCore import Qt, QTimer
class AnimationWindows(QWidget):
def __init__(self, parent=None):
super(AnimationWindows, self).__init__(parent)
self.i = 1
self.mypix()
self.timer = QTimer()
self.timer.setInterval(500) # 500毫秒
self.timer.timeout.connect(self.timeChange)
self.timer.start()
# 显示不规则 pic
def mypix(self):
self.update()
if self.i == 5:
self.i = 1
self.mypic = {1: './images/left.png', 2: "./images/up.png", 3: './images/right.png', 4: './images/down.png'}
self.pix = QPixmap(self.mypic[self.i])
self.resize(self.pix.size())
self.setMask(self.pix.mask())
self.dragPosition = None
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.m_drag = True
self.m_DragPosition = event.globalPos() - self.pos()
self.setCursor(QCursor(Qt.OpenHandCursor))
def mouseMoveEvent(self, QMouseEvent):
if Qt.LeftButton and self.m_drag:
self.move(QMouseEvent.globalPos() - self.m_DragPosition)
def mouseReleaseEvent(self, QMouseEvent):
self.m_drag = False
self.setCursor(QCursor(Qt.ArrowCursor))
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(0, 0, self.pix.width(), self.pix.height(), self.pix)
# 鼠标双击事件
def mouseDoubleClickEvent(self, event):
if event.button() == 1:
self.i += 1
self.mypix()
# 每500毫秒修改paint
def timeChange(self):
self.i += 1
self.mypix()
if __name__ == '__main__':
app = QApplication(sys.argv)
form = AnimationWindows()
form.show()
sys.exit(app.exec_())
用动画效果改变窗口尺寸
'''
用动画效果改变窗口尺寸
QPropertyAnimation
'''
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class AnimWindow(QWidget):
def __init__(self):
super(AnimWindow, self).__init__()
self.OrigHeight = 50
self.ChangeHeight = 150
self.setGeometry(QRect(500, 400, 150, self.OrigHeight))
self.btn = QPushButton('展开', self)
self.btn.setGeometry(10, 10, 60, 35)
self.btn.clicked.connect(self.change)
def change(self):
currentHeight = self.height()
if self.OrigHeight == currentHeight:
startHeight = self.OrigHeight
endHeight = self.ChangeHeight
self.btn.setText('收缩')
else:
startHeight = self.ChangeHeight
endHeight= self.OrigHeight
self.btn.setText('展开')
self.animation = QPropertyAnimation(self,b'geometry')
self.animation.setDuration(500)
self.animation.setStartValue(QRect(500,400,150,startHeight))
self.animation.setEndValue(QRect(500,400,150,endHeight))
self.animation.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = AnimWindow()
window.show()
sys.exit(app.exec_())
用动画效果一不同速度移动窗口
'''
用动画效果一不同速度移动窗口
'''
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
app = QApplication(sys.argv)
window1 = QMainWindow()
window1.show()
window2 = QMainWindow()
window2.show()
animation1 = QPropertyAnimation(window1, b'geometry')
animation2 = QPropertyAnimation(window2, b'geometry')
group = QParallelAnimationGroup() # 并行
group = QSequentialAnimationGroup() # 串行
group.addAnimation(animation1)
group.addAnimation(animation2)
animation1.setDuration(3000)
animation1.setStartValue(QRect(0,0,100,30))
animation1.setEndValue(QRect(250,250,100,30))
animation1.setEasingCurve(QEasingCurve.OutBounce)
animation2.setDuration(4000)
animation2.setStartValue(QRect(250,150,100,30))
animation2.setEndValue(QRect(850,250,100,30))
animation2.setEasingCurve(QEasingCurve.CosineCurve)
group.start()
sys.exit(app.exec())
装载Gif动画
'''
装载Gif动画
QMovie
'''
import sys
from PyQt5.QtWidgets import QApplication, QLabel ,QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QMovie
class LoadingGif(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel("",self)
self.setFixedSize(128,128)
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)
self.movie = QMovie('./images/loading.gif')
self.label.setMovie(self.movie)
self.movie.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = LoadingGif()
form.show()
sys.exit(app.exec_())
使用QSS为标签和按钮添加背景图
'''
使用QSS为标签和按钮添加背景图
'''
from PyQt5.QtWidgets import *
import sys
class LabelButtonBackground(QWidget):
def __init__(self):
super().__init__()
label1 = QLabel(self)
label1.setToolTip('这是一个文本标签')
label1.setStyleSheet('QLabel{border-image:url(./images/python.jpg);}')
label1.setFixedWidth(476)
label1.setFixedHeight(259)
btn1 = QPushButton(self)
btn1.setObjectName('btn1')
btn1.setMaximumSize(48,48)
btn1.setMinimumSize(48,48)
style = '''
#btn1{
border-radius:4px;
background-image:url('./images/add.png');
}
#btn1:Pressed {
background-image:url('./images/addhover.png');
}
'''
btn1.setStyleSheet(style)
vbox = QVBoxLayout()
vbox.addWidget(label1)
vbox.addStretch()
vbox.addWidget(btn1)
self.setLayout(vbox)
self.setWindowTitle('使用QSS为标签和按钮添加背景图')
if __name__ == "__main__":
app = QApplication(sys.argv)
form = LabelButtonBackground()
form.show()
sys.exit(app.exec_())
缩放图片
'''
缩放图片
QImage.scaled
'''
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import Qt
import sys
class ScaleImage(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("图片大小缩放例子")
filename = './images/Cloudy_72px.png'
img = QImage(filename)
label1 = QLabel(self)
label1.setFixedWidth(200)
label1.setFixedHeight(200)
result = img.scaled(label1.width(),label1.height(),Qt.IgnoreAspectRatio,Qt.SmoothTransformation)
label1.setPixmap(QPixmap.fromImage(result))
vbox = QVBoxLayout()
vbox.addWidget(label1)
self.setLayout(vbox)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = ScaleImage()
win.show()
sys.exit(app.exec_())
创建透明窗口
'''
创建透明窗口
'''
from PyQt5.Qt import *
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
win = QMainWindow()
win.setWindowTitle('窗口的透明度设置')
# 0到1,1表示不透明,0表示完全透明
win.setWindowOpacity(0.6)
button = QPushButton('我的按钮',win)
win.resize(400,200)
win.show()
sys.exit(app.exec())
装载QSS文件
'''
装载QSS文件
'''
import sys
from PyQt5.QtWidgets import *
from CommonHelper import CommonHelper
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(477, 258)
self.setWindowTitle("加载QSS文件")
btn = QPushButton()
btn.setText('装载QSS文件')
btn.setToolTip('提示文本')
vbox = QVBoxLayout()
vbox.addWidget(btn)
btn.clicked.connect(self.onClick)
self.setLayout(vbox)
widget = QWidget(self)
self.setCentralWidget(widget)
widget.setLayout(vbox)
def onClick(self):
styleFile = './style.qss'
qssStyle = CommonHelper.readQSS(styleFile)
win.setStyleSheet(qssStyle)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
style.qss
QMainWindow{
border-image:url(./images/python.jpg);
}
QToolTip {
border:1px solid rgb(45,45,45);
background:white;
color:red
}
CommonHelper.py
class CommonHelper:
@staticmethod
def readQSS(style):
with open(style,'r') as f:
return f.read()