如图,当鼠标进入tablewidgetitem时,图片的标题会显示出来。标题文本的颜色,通过CalculateTextColor类计算出来(图片平均颜色的对比色)。但是我发现,计算的时间有点长,六七秒才会变颜色,而且期间CPU的占用很大,达到百分之四五十。
耗费时间长和资源占用多的问题该怎么解决?
如果不计算对比色,可以设置一下标题的背景颜色,这样虽然一劳永逸,但是总感觉标题和图片的界限太明显,影响观感。除此之外,有没有其他的方案,避免字体颜色和壁纸颜色相近?
以下是代码:
import sys
from os import chdir, path
from time import sleep
import requests
from PySide6.QtWidgets import QSizePolicy, QVBoxLayout, QWidget, QHBoxLayout, QToolTip, QPushButton, QLabel, QTableWidget,\
QApplication, QAbstractItemView, QDialog
from PySide6.QtGui import QIcon, QPixmap, QColor
from PySide6.QtCore import Qt, QThread, Signal
filepath = path.abspath(__file__)
chdir(path.dirname(filepath))
class Ui_Form(QWidget):
blankRow = 0
blankColumn = 0
def __init__(self, rule):
super().__init__()
self.rule = rule
self.setupUi(self, rule)
self.show()
def setupUi(self, Form, rule):
# 窗体基本设置
Form.resize(1300, 700)
Form.setWindowTitle(rule['name'])
self.setWindowFlags(Qt.FramelessWindowHint) # 去掉窗口标题栏
self.setMouseTracking(True) # 跟踪鼠标移动
mainLayout = QVBoxLayout(Form)
mainLayout.setContentsMargins(0, 0, 0, 0)
# 标题栏
self.logoLabel = QLabel()
self.logoLabel.setFixedSize(30, 30)
self.I = Img(rule['logoUrl'])
self.I.imgSin.connect(self.setLogo)
self.I.start()
titleLabel = QLabel(objectName='titleLabel')
titleLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
titleLabel.setText(rule['name'])
titleBar = QWidget(objectName='titleBar')
titleBar.setMaximumHeight(40)
mainLayout.addWidget(titleBar)
titleBarLayout = QHBoxLayout(titleBar, spacing=0)
titleBarLayout.setContentsMargins(0, 0, 0, 0)
self.copyurlButton = QPushButton(clicked=self.copyUrl, objectName='copyurlButton')
self.copyurlButton.setFixedSize(40, 30)
self.copyurlButton.setIcon(QIcon(QPixmap('./img/url.png')))
self.copyurlButton.setToolTip('复制网址')
minimizeButton = QPushButton(clicked=self.showMinimized, objectName='minimizeButton')
minimizeButton.setFixedSize(40, 30)
minimizeButton.setIcon(QIcon(QPixmap('./img/minimize.png')))
self.maximizeButton = QPushButton(clicked=self.maximized, objectName='maximizeButton') # 需要实现两个功能:最大化和恢复正常,所以自定义 self.maximized()
self.maximizeButton.setFixedSize(40, 30)
self.maximizeButton.setIcon(QIcon(QPixmap('./img/maximize.png')))
closeButton = QPushButton(clicked=self.close, objectName='closeButton')
closeButton.setFixedSize(40, 30)
closeButton.setIcon(QIcon(QPixmap('./img/close.png')))
titleBarLayout.addWidget(self.logoLabel)
titleBarLayout.addSpacing(10) # 设置 logo 和 title 的间隔
titleBarLayout.addWidget(titleLabel, alignment=Qt.AlignLeft)
titleBarLayout.addWidget(self.copyurlButton)
titleBarLayout.addWidget(minimizeButton)
titleBarLayout.addWidget(self.maximizeButton)
titleBarLayout.addWidget(closeButton)
imgUrl = ' http://img.netbian.com/file/2023/0305/small180944SteRA1678010984.jpg'
imgTitle = '白色衣服长发古风古装美女动漫壁纸'
# 内容区
self.picTable = QTableWidget(8, 3)
self.picTable.setShowGrid(False) # 隐藏网格线
self.picTable.setMinimumSize(1250, 600) # 设置最小尺寸
self.picTable.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) # 设置垂直滚动条像素级滚动
self.picTable.setEditTriggers(QAbstractItemView.NoEditTriggers) # 禁止编辑
self.picTable.setSelectionMode(QAbstractItemView.ContiguousSelection) # 设置选择模式
horizontalHeader = self.picTable.horizontalHeader()
horizontalHeader.setVisible(False) # 隐藏水平表头
horizontalHeader.setDefaultSectionSize(410) # 设置列宽
verticalHeader = self.picTable.verticalHeader()
verticalHeader.setVisible(False) # 隐藏垂直表头
verticalHeader.setDefaultSectionSize(235) # 设置行高
mainLayout.addWidget(self.picTable, alignment=Qt.AlignHCenter)
for i in range(6):
imgLabel = ImgCell(imgTitle, imgUrl)
self.picTable.setCellWidget(self.blankRow, self.blankColumn, imgLabel)
self.calculatePos() # 更新空白单元格的位置
def copyUrl(self):
app = QApplication.instance()
app.clipboard().setText(self.rule['baseUrl'])
self.copyurlButton.setIcon(QIcon(QPixmap('./img/copied.png')))
self.C = Copy()
self.C.copySin.connect(lambda: self.copyurlButton.setIcon(QIcon(QPixmap('./img/url.png'))))
self.C.start()
QToolTip.showText(self.cursor().pos(), '复制成功')
def maximized(self):
# 窗口最大化和恢复正常
if self.isMaximized():
self.showNormal()
self.maximizeButton.setIcon(QIcon(QPixmap('./img/maximize.png')))
else:
self.showMaximized()
self.maximizeButton.setIcon(QIcon(QPixmap('./img/normal.png')))
def setLogo(self, sin):
if isinstance(sin, bytes):
logo = QPixmap()
logo.loadFromData(sin)
self.logoLabel.setPixmap(logo)
else:
pass
def calculatePos(self):
# 计算空白的位置
if self.blankColumn < 2:
self.blankColumn += 1
else:
self.blankRow += 1
self.blankColumn = 0
class Copy(QThread):
copySin = Signal(bool)
def __init__(self):
super().__init__()
def run(self):
sleep(2)
self.copySin.emit(True)
class Img(QThread):
imgSin = Signal(object)
def __init__(self, imgUrl):
super().__init__()
self.imgUrl = imgUrl
def run(self):
while True:
try:
imgContent = requests.get(self.imgUrl, headers={'user-agent': 'Chrome/110.0.0.0'}).content
self.imgSin.emit(imgContent)
break
except:
self.imgSin.emit(False)
class ImgCell(QLabel):
def __init__(self, imgTitle, imgUrl):
super().__init__()
self.imgTitle = imgTitle
self.imgUrl = imgUrl
self.setupUi()
def setupUi(self):
self.setFixedSize(400, 225)
self.setScaledContents(True)
self.I = Img(self.imgUrl)
self.I.imgSin.connect(self.setImg)
self.I.start()
self.titleLabel = QLabel()
self.titleLabel.setWordWrap(True) # 允许换行显示
self.titleLabel.setText(self.imgTitle)
self.titleLabel.hide()
self.bigButton = QPushButton(clicked=self.bigImg)
self.bigButton.setFixedSize(20, 20)
self.bigButton.setStyleSheet('background-color: rgba(255, 255, 255, 128); border-radius: 5px') # 设置透明度和圆角
self.bigButton.setIcon(QIcon(QPixmap('./img/big.png')))
self.bigButton.setToolTip('放大')
self.bigButton.hide()
self.dlButton = QPushButton()
self.dlButton.setFixedSize(20, 20)
self.dlButton.setStyleSheet('background-color: rgba(255, 255, 255, 128); border-radius: 5px')
self.dlButton.setIcon(QIcon(QPixmap('./img/download.png')))
self.dlButton.setToolTip('下载')
self.dlButton.hide()
self.copyurlButton = QPushButton(clicked=self.copyUrl, objectName='copyurlButton')
self.copyurlButton.setFixedSize(20, 20)
self.copyurlButton.setStyleSheet('background-color: rgba(255, 255, 255, 128); border-radius: 5px')
self.copyurlButton.setIcon(QIcon(QPixmap('./img/url.png')))
self.copyurlButton.setToolTip('复制网址')
self.copyurlButton.hide()
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(self.bigButton)
buttonLayout.addWidget(self.dlButton)
buttonLayout.addWidget(self.copyurlButton)
buttonLayout.setSpacing(5)
layout = QVBoxLayout(self)
layout.addWidget(self.titleLabel, alignment=Qt.AlignTop)
layout.addLayout(buttonLayout)
layout.setAlignment(buttonLayout, Qt.AlignRight | Qt.AlignBottom)
def copyUrl(self):
app = QApplication.instance()
app.clipboard().setText(self.imgUrl)
self.copyurlButton.setIcon(QIcon(QPixmap('./img/copied.png')))
self.copyurlButton.setEnabled(False)
self.C = Copy()
self.C.copySin.connect(self.copied)
self.C.start()
QToolTip.showText(self.cursor().pos(), '复制成功')
def copied(self):
# 复制结束后
self.copyurlButton.setIcon(QIcon(QPixmap('./img/url.png')))
self.copyurlButton.setEnabled(True)
def setImg(self, img):
self.img = img
imgPixmap = QPixmap()
imgPixmap.loadFromData(img)
self.setPixmap(imgPixmap)
self.CTC = CalculateTextColor(img)
self.CTC.colorSin.connect(lambda color: self.titleLabel.setStyleSheet(f'color: {color}'))
self.CTC.start()
def enterEvent(self, event):
self.titleLabel.show()
self.bigButton.show()
self.dlButton.show()
self.copyurlButton.show()
def leaveEvent(self, event):
self.titleLabel.hide()
self.bigButton.hide()
self.dlButton.hide()
self.copyurlButton.hide()
def bigImg(self):
self.BI = BigImg(self.img)
class CalculateTextColor(QThread):
# 计算图片的对比色
colorSin = Signal(str)
def __init__(self, pixmap):
super().__init__()
self.pixmapData = pixmap
def run(self):
# 计算图片的平均颜色
pixmap = QPixmap()
pixmap.loadFromData(self.pixmapData)
img = pixmap.toImage()
width, height = img.width(), img.height()
red = green = blue = 0
for x in range(width):
for y in range(height):
pixel = QColor(img.pixel(x, y))
red += pixel.red()
green += pixel.green()
blue ++ pixel.blue()
totalPixels = width * height
avgColor = QColor(red//totalPixels, green//totalPixels, blue//totalPixels)
color = avgColor.lighter().name() # 计算对比色
self.colorSin.emit(color)
class BigImg(QDialog):
# 完全显示缩略图
# bigimgSin = Signal
def __init__(self, pixmap):
super().__init__()
self.setupUi(pixmap)
def setupUi(self, img):
imgLabel = QLabel(self)
pixmap = QPixmap()
pixmap.loadFromData(img)
imgLabel.setPixmap(pixmap)
imgLabel.adjustSize()
self.show()
def leaveEvent(self, event):
self.close()
if __name__ == '__main__':
styleSheet = '''
#titleBar {
background-color: #bdbdbd
}
#titleLabel {
font-family: 小米兰亭;
font-size: 20px
}
/*复制网址、最小化、最大化、关闭按钮通用默认背景*/
#copyurlButton, #minimizeButton, #maximizeButton, #closeButton {
border: 0;
}
/*悬停*/
#copyurlButton, #minimizeButton:hover, #maximizeButton:hover {
background-color: #a6a6a6
}
#closeButton:hover {
background-color: red
}
QTableWidget {
border: 0;
background-color: #f0f0f0
}
/*设置单元格的内容边距*/
QTableWidget::item {
padding: 5
}
/*图片弄成圆角比较麻烦,先不搞了*/
QLabel {
border: 2px;
}
'''
app = QApplication(sys.argv)
app.setStyleSheet(styleSheet)
rule = {'name': '彼岸桌面', 'baseUrl': 'http://www.netbian.com', "logoUrl": "http://www.netbian.com/favicon.ico"}
ui = Ui_Form(rule) # 创建 PyQt 设计的窗体对象
sys.exit(app.exec()) # 程序关闭时退出进程