QPainter 绘图 ( 储存图片 )
这篇教学会使用 PyQt6 的 QPainter() 搭配 QPixmap(),让 QPainter() 所绘制的图片可以储存到电脑中。
快速导览:
因为 Google Colab 不支援 PyQt6,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。
使用 QPainter() 搭配 QPixmap()
在“QPainter 绘图”的教学范例中,是利用 QPainter() 对象在主视窗的背景绘图,但许多实际的状况并不会在主视窗的背景绘图,而是会使用 QPixmap() 对象作为“画布”,在画布进行作画,下方的程序码执行后,会产生一个 QPixmap() 对象,在这个对象上作画之后,再透过 QLabel() 呈现出绘图的内容。
from PyQt6 import QtWidgets
from PyQt6.QtGui import *
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
MainWindow.setObjectName("MainWindow")
MainWindow.setWindowTitle("oxxo.studio")
MainWindow.resize(300, 200)
label = QtWidgets.QLabel(MainWindow) # 建立 QLabel
label.setGeometry(0, 20, 300, 180) # 設定位置 ( 最上方留下 20px 空間 )
def draw(self):
canvas = QPixmap(300,180) # 新增 QPixmap 物件為畫布
canvas.fill(QColor('#ffdddd')) # 設定畫布背景
qpainter = QPainter() # 建立 QPainter() 物件
qpainter.begin(canvas) # 綁定 canvas 進行繪畫
qpainter.setPen(QPen(QColor('#ff0000'), 5)) # 繪製紅色矩形
qpainter.drawRect(10,10,100,100)
qpainter.setPen(QPen(QColor('#00aa00'), 5)) # 繪製綠色橢圓
qpainter.drawEllipse(50, 50, 100, 100)
qpainter.setPen(QPen(QColor('#000000'), 5)) # 繪製黑色直線
qpainter.drawLine(100,100,300,200)
qpainter.end() # 繪圖結束
label.setPixmap(canvas) # 將 canvas 放入 QLabel 中
MainWindow.paintEvent = draw
MainWindow.show()
sys.exit(app.exec())
class 写法:
from PyQt6 import QtWidgets
from PyQt6.QtGui import *
from PyQt6.QtCore import *
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setObjectName("MainWindow")
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self) # 建立 QLabel
self.label.setGeometry(0, 20, 300, 180) # 設定位置 ( 最上方留下 20px 空間 )
self.canvas = QPixmap(300,180) # 新增 QPixmap 物件為畫布
self.canvas.fill(QColor('#ffdddd')) # 設定畫布背景
def paintEvent(self, event):
self.qpainter = QPainter() # 建立 QPainter() 物件
self.qpainter.begin(self.canvas) # 綁定 canvas 進行繪畫
self.qpainter.setPen(QPen(QColor('#ff0000'), 5)) # 繪製紅色矩形
self.qpainter.drawRect(10,10,100,100)
self.qpainter.setPen(QPen(QColor('#00aa00'), 5)) # 繪製綠色橢圓
self.qpainter.drawEllipse(50, 50, 100, 100)
self.qpainter.setPen(QPen(QColor('#000000'), 5)) # 繪製黑色直線
self.qpainter.drawLine(100,100,300,200)
self.qpainter.end() # 繪圖結束
self.label.setPixmap(self.canvas) # 將 canvas 放入 QLabel 中
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
QPixmap() 储存图片
当作为画布的 QPixmap() 对象已经绘制完成后,就能透过 save() 方法,将绘制的内容储存成图片,save() 的用法如下:
canvas = QPixmap(width, height)
canvas.save(name, fomat, quality)
修改前一段的程序码,加入按钮的功能,就能在点击按钮的当下,将 QPixmap() 对象储存成指定格式的图片。
from PyQt6 import QtWidgets
from PyQt6.QtGui import *
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
MainWindow.setObjectName("MainWindow")
MainWindow.setWindowTitle("oxxo.studio")
MainWindow.resize(300, 200)
label = QtWidgets.QLabel(MainWindow)
label.setGeometry(0, 30, 300, 170)
def save(format):
if format == 'jpg':
label.pixmap().save('demo.jpg','JPG',90) # 儲存為 jpg
else:
label.pixmap().save('demo.png','PNG') # 儲存為 png
btn1 = QtWidgets.QPushButton(MainWindow)
btn1.setText('儲存為 jpg')
btn1.setGeometry(20,0,100,30)
btn1.clicked.connect(lambda: save('jpg')) # 綁定儲存的函式
btn2 = QtWidgets.QPushButton(MainWindow)
btn2.setText('儲存為 png')
btn2.setGeometry(120,0,100,30)
btn2.clicked.connect(lambda: save('png')) # 綁定儲存的函式
def draw(self):
canvas = QPixmap(300,170)
canvas.fill(QColor('#ffdddd'))
qpainter = QPainter()
qpainter.begin(canvas)
qpainter.setPen(QPen(QColor('#ff0000'), 5))
qpainter.drawRect(10,10,100,100)
qpainter.setPen(QPen(QColor('#00aa00'), 5))
qpainter.drawEllipse(50, 50, 100, 100)
qpainter.setPen(QPen(QColor('#000000'), 5))
qpainter.drawLine(100,100,300,200)
qpainter.end()
label.setPixmap(canvas)
MainWindow.paintEvent = draw
MainWindow.show()
sys.exit(app.exec())
class 的写法:
from PyQt6 import QtWidgets
from PyQt6.QtGui import *
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(0, 30, 300, 170)
self.btn1 = QtWidgets.QPushButton(self)
self.btn1.setText('儲存為 jpg')
self.btn1.setGeometry(20,0,100,30)
self.btn1.clicked.connect(lambda: self.save('jpg')) # 綁定儲存的函式
self.btn2 = QtWidgets.QPushButton(self)
self.btn2.setText('儲存為 png')
self.btn2.setGeometry(120,0,100,30)
self.btn2.clicked.connect(lambda: self.save('png')) # 綁定儲存的函式
def save(self, format):
if format == 'jpg':
self.label.pixmap().save('demo.jpg','JPG',90) # 儲存為 jpg
else:
self.label.pixmap().save('demo.png','PNG') # 儲存為 png
def paintEvent(self, event):
canvas = QPixmap(300,170)
canvas.fill(QColor('#ffdddd'))
qpainter = QPainter()
qpainter.begin(canvas)
qpainter.setPen(QPen(QColor('#ff0000'), 5))
qpainter.drawRect(10,10,100,100)
qpainter.setPen(QPen(QColor('#00aa00'), 5))
qpainter.drawEllipse(50, 50, 100, 100)
qpainter.setPen(QPen(QColor('#000000'), 5))
qpainter.drawLine(100,100,300,200)
qpainter.end()
self.label.setPixmap(canvas)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
微信扫码关注
抖音扫码关注