在用designer进行界面布局时,可能会存在现有控件无法满足需求,需要使用自定义控件的情况。一般这个时候我们可以在代码里对自定义控件进行实例化调用,也可以在designer界面将一个普通控件提升为自定义控件。
以这个自定义QWidget控件(含有显示两种字体和图片的按钮的widget)为例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
from PyQt5.QtGui import QTextDocument, QImage, QPainter, QPixmap, QIcon, QColor
from PyQt5.QtCore import Qt
class MyButtonWidget(QWidget):
def __init__(self):
super().__init__()
self.my_width, self.my_height = 300,60
# self.initUI()
def initUI(self):
str1 ='这个字体很大...'
str2 = '这个字体很小...'
html_text = f"<span style='font-size: 19pt; font-family:Microsoft YaHei UI;font-weight:400; font-style:normal;'>" \
f"{str1}</span><br><span style='font-size: 11pt;font-family:Microsoft YaHei UI;'>{str2}</span>"
layout = QVBoxLayout()
button = QPushButton()
# 将HTML文本渲染为图像
image = self.htmlToImage(html_text)
# 创建图标并设置给按钮
icon = QIcon(QPixmap.fromImage(image))
able_icon = QIcon()
able_icon.addPixmap(QPixmap(r"C:\Users\ASUS\Desktop\11.jpg"), QIcon.Normal, QIcon.Off)
combined_icon = self.combineIcons(able_icon, icon) # 合并两个图标
button.setIcon(combined_icon)
button.setIconSize(image.size())
button.setMaximumSize(self.my_width, self.my_height)
layout.addWidget(button)
self.setLayout(layout)
self.setGeometry(100, 100, 400, 110)
self.setWindowTitle('按钮显示两张图片+HTML文本转图片示例')
def combineIcons(self, icon1, icon2):
pixmap1 = icon1.pixmap(35, 35)
pixmap2 = icon2.pixmap(270, 40)
combined_pixmap = QPixmap(300, 40)
combined_pixmap.fill(Qt.transparent)
painter = QPainter()
painter.begin(combined_pixmap)
painter.drawPixmap(5, 5, pixmap1)
painter.drawPixmap(40, 0, pixmap2) # 第二个图标偏移一半的宽度
painter.end()
combined_icon = QIcon(combined_pixmap)
return combined_icon
def htmlToImage(self, html_text):
document = QTextDocument()
document.setHtml(html_text)
# 渲染文档到图像
image = QImage(self.my_width, self.my_height, QImage.Format_ARGB32)
image.fill(QColor(0, 0, 0, 0)) # 设置透明背景
painter = QPainter(image)
document.drawContents(painter)
painter.end()
return image
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyButtonWidget()
window.show()
sys.exit(app.exec_())
首先,在designer里面,我们鼠标右键要提升的控件,点击提升为。
然后弹出提升部件窗口,在提升的类名称后面输入:自定义控件的类名称(我的自定义控件类名称(类名)是MyButtonWidget)
头文件输入:自定义控件的类文件在在工程里路径, /换成. 、 .py换成.h
(我的是my_widget/widget_test.py, 所以写成: my_widget.widget_test.h)
输入完,点击添加,点击提升即可。
保存后,将ui转成.py文件。(.ui转.py可参考:http://t.csdnimg.cn/GuKVE)
可以在这个转成的.py文件发现已经引用了这个自定义控件。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = MyButtonWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(270, 200, 261, 191))
self.widget.setStyleSheet("background-color: rgb(200, 222, 220);")
self.widget.setObjectName("widget")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
from my_widget.widget_test import MyButtonWidget
运行看看效果:
from untitled import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow, QApplication
import sys
class MyMainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.setupUi(self)
self.widget.initUI()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyMainWindow()
window.show()
sys.exit(app.exec_())