This commit is contained in:
睿 安
2026-01-21 16:48:36 +08:00
commit abba5cb273
246 changed files with 57473 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
from datetime import datetime
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import *
from app import person
class ContactUi(QtWidgets.QPushButton):
"""
联系人类继承自pyqt的按钮里面封装了联系人头像等标签
"""
usernameSingal = pyqtSignal(str)
def __init__(self, Ui, id=None, rconversation=None):
super(ContactUi, self).__init__(Ui)
self.contact: person.Contact = person.Contact(rconversation[1])
self.init_ui(Ui)
self.msgCount = rconversation[0]
self.username = rconversation[1]
self.conversationTime = rconversation[6]
self.msgType = rconversation[7]
self.digest = rconversation[8]
hasTrunc = rconversation[10]
attrflag = rconversation[11]
if hasTrunc == 0:
if attrflag == 0:
self.digest = '[动画表情]'
elif attrflag == 67108864:
try:
remark = data.get_conRemark(rconversation[9])
msg = self.digest.split(':')[1].strip('\n').strip()
self.digest = f'{remark}:{msg}'
except Exception as e:
pass
else:
pass
self.show_info(id)
def init_ui(self, Ui):
self.layoutWidget = QtWidgets.QWidget(Ui)
self.layoutWidget.setObjectName("layoutWidget")
self.gridLayout1 = QtWidgets.QGridLayout(self.layoutWidget)
self.gridLayout1.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
self.gridLayout1.setContentsMargins(10, 10, 10, 10)
self.gridLayout1.setSpacing(10)
self.gridLayout1.setObjectName("gridLayout1")
self.label_time = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(8)
self.label_time.setFont(font)
self.label_time.setLayoutDirection(QtCore.Qt.RightToLeft)
self.label_time.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.label_time.setObjectName("label_time")
self.gridLayout1.addWidget(self.label_time, 0, 2, 1, 1)
self.label_remark = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("黑体")
font.setPointSize(10)
# font.setBold(True)
self.label_remark.setFont(font)
self.label_remark.setObjectName("label_remark")
self.gridLayout1.addWidget(self.label_remark, 0, 1, 1, 1)
self.label_msg = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setPointSize(8)
self.label_msg.setFont(font)
self.label_msg.setObjectName("label_msg")
self.gridLayout1.addWidget(self.label_msg, 1, 1, 1, 2)
self.label_avatar = QtWidgets.QLabel(self.layoutWidget)
self.label_avatar.setMinimumSize(QtCore.QSize(60, 60))
self.label_avatar.setMaximumSize(QtCore.QSize(60, 60))
self.label_avatar.setLayoutDirection(QtCore.Qt.RightToLeft)
self.label_avatar.setAutoFillBackground(False)
self.label_avatar.setStyleSheet("background-color: #ffffff;")
self.label_avatar.setInputMethodHints(QtCore.Qt.ImhNone)
self.label_avatar.setFrameShape(QtWidgets.QFrame.NoFrame)
self.label_avatar.setFrameShadow(QtWidgets.QFrame.Plain)
self.label_avatar.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label_avatar.setObjectName("label_avatar")
self.gridLayout1.addWidget(self.label_avatar, 0, 0, 2, 1)
self.gridLayout1.setColumnStretch(0, 1)
self.gridLayout1.setColumnStretch(1, 6)
self.gridLayout1.setRowStretch(0, 5)
self.gridLayout1.setRowStretch(1, 3)
self.setLayout(self.gridLayout1)
self.setStyleSheet(
"QPushButton {background-color: rgb(220,220,220);}"
"QPushButton:hover{background-color: rgb(208,208,208);}\n"
)
def show_info(self, id):
time = datetime.now().strftime("%m-%d %H:%M")
msg = '还没说话'
self.label_avatar.setPixmap(self.contact.avatar) # 在label上显示图片
self.label_remark.setText(self.contact.conRemark)
self.label_msg.setText(self.digest)
self.label_time.setText(data.timestamp2str(self.conversationTime)[2:])
def show_msg(self):
self.usernameSingal.emit(self.username)

303
app/components/CAvatar.py Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2020年3月13日
@author: Irony
@site: https://pyqt.site , https://github.com/PyQt5
@email: 892768447@qq.com
@file: Demo.Lib.QCursorGif
@description:
"""
try:
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QCursor, QPixmap
from PyQt5.QtWidgets import QApplication
except ImportError:
from PySide2.QtCore import QTimer, Qt
from PySide2.QtGui import QCursor, QPixmap
from PySide2.QtWidgets import QApplication
from app.resources import resource_rc
var = resource_rc.qt_resource_name
class QCursorGif:
def initCursor(self, cursors, parent=None):
# 记录默认的光标
self._oldCursor = Qt.ArrowCursor
self.setOldCursor(parent)
# 加载光标图片
self._cursorImages = [
QCursor(QPixmap(cursor)) for cursor in cursors]
self._cursorIndex = 0
self._cursorCount = len(self._cursorImages) - 1
# 创建刷新定时器
self._cursorTimeout = 200
self._cursorTimer = QTimer(parent)
self._cursorTimer.timeout.connect(self._doBusy)
self.num = 0
def _doBusy(self):
if self._cursorIndex > self._cursorCount:
self._cursorIndex = 0
QApplication.setOverrideCursor(
self._cursorImages[self._cursorIndex])
self._cursorIndex += 1
self.num += 1
def startBusy(self):
# QApplication.setOverrideCursor(Qt.WaitCursor)
if not self._cursorTimer.isActive():
self._cursorTimer.start(self._cursorTimeout)
def stopBusy(self):
self._cursorTimer.stop()
QApplication.restoreOverrideCursor()
# 将光标出栈,恢复至原始状态
for i in range(self.num):
QApplication.restoreOverrideCursor()
self.num = 0
def setCursorTimeout(self, timeout):
self._cursorTimeout = timeout
def setOldCursor(self, parent=None):
QApplication.overrideCursor()
self._oldCursor = (QApplication.overrideCursor() or parent.cursor() or Qt.ArrowCursor or Qt.IBeamCursor) if parent else (
QApplication.overrideCursor() or Qt.ArrowCursor)

View File

@@ -0,0 +1,2 @@
from .contact_info_ui import ContactQListWidgetItem
from .scroll_bar import ScrollBar

View File

@@ -0,0 +1,301 @@
import os.path
import subprocess
import platform
from PyQt5 import QtGui
from PyQt5.QtCore import QSize, pyqtSignal, Qt, QThread
from PyQt5.QtGui import QPainter, QFont, QColor, QPixmap, QPolygon, QFontMetrics
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QSizePolicy, QVBoxLayout, QSpacerItem, \
QScrollArea
from app.components.scroll_bar import ScrollBar
class MessageType:
Text = 1
Image = 3
class TextMessage(QLabel):
heightSingal = pyqtSignal(int)
def __init__(self, text, is_send=False, parent=None):
if isinstance(text, bytes):
text = text.decode('utf-8')
super(TextMessage, self).__init__(text, parent)
font = QFont('微软雅黑', 12)
self.setFont(font)
self.setWordWrap(True)
self.setMaximumWidth(800)
# self.setMinimumWidth(100)
self.setMinimumHeight(45)
self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
if is_send:
self.setAlignment(Qt.AlignCenter | Qt.AlignRight)
self.setStyleSheet(
'''
background-color:#b2e281;
border-radius:10px;
padding:10px;
'''
)
else:
self.setStyleSheet(
'''
background-color:white;
border-radius:10px;
padding:10px;
'''
)
font_metrics = QFontMetrics(font)
rect = font_metrics.boundingRect(text)
# rect = font_metrics
self.setMaximumWidth(rect.width() + 40)
def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
super(TextMessage, self).paintEvent(a0)
class Triangle(QLabel):
def __init__(self, Type, is_send=False, position=(0, 0), parent=None):
"""
@param Type:
@param is_send:
@param position:(x,y)
@param parent:
"""
super().__init__(parent)
self.Type = Type
self.is_send = is_send
self.position = position
def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
super(Triangle, self).paintEvent(a0)
if self.Type == MessageType.Text:
self.setFixedSize(6, 45)
painter = QPainter(self)
triangle = QPolygon()
x, y = self.position
if self.is_send:
painter.setPen(QColor('#b2e281'))
painter.setBrush(QColor('#b2e281'))
triangle.setPoints(0, 20+y, 0, 34+y, 6, 27+y)
else:
painter.setPen(QColor('white'))
painter.setBrush(QColor('white'))
triangle.setPoints(0, 27+y, 6, 20+y, 6, 34+y)
painter.drawPolygon(triangle)
class Notice(QLabel):
def __init__(self, text, type_=3, parent=None):
super().__init__(text, parent)
self.type_ = type_
self.setFont(QFont('微软雅黑', 10))
self.setWordWrap(True)
self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setAlignment(Qt.AlignCenter)
class Avatar(QLabel):
def __init__(self, avatar, parent=None):
super().__init__(parent)
if isinstance(avatar, str):
self.setPixmap(QPixmap(avatar).scaled(45, 45))
self.image_path = avatar
elif isinstance(avatar, QPixmap):
self.setPixmap(avatar.scaled(45, 45))
self.setFixedSize(QSize(45, 45))
def open_image_viewer(file_path):
system_platform = platform.system()
if system_platform == "Darwin": # macOS
subprocess.run(["open", file_path])
elif system_platform == "Windows":
subprocess.run(["start", " ", file_path], shell=True)
elif system_platform == "Linux":
subprocess.run(["xdg-open", file_path])
else:
print("Unsupported platform")
class OpenImageThread(QThread):
def __init__(self, image_path):
super().__init__()
self.image_path = image_path
def run(self) -> None:
if os.path.exists(self.image_path):
open_image_viewer(self.image_path)
class ImageMessage(QLabel):
def __init__(self, image, is_send, image_link='', max_width=480, max_height=240, parent=None):
"""
param:image 图像路径或者QPixmap对象
param:image_link='' 点击图像打开的文件路径
"""
super().__init__(parent)
self.image = QLabel(self)
self.max_width = max_width
self.max_height = max_height
# self.setFixedSize(self.max_width,self.max_height)
self.setMaximumWidth(self.max_width)
self.setMaximumHeight(self.max_height)
self.setCursor(Qt.PointingHandCursor)
if isinstance(image, str):
pixmap = QPixmap(image)
self.image_path = image
elif isinstance(image, QPixmap):
pixmap = image
self.set_image(pixmap)
if image_link:
self.image_path = image_link
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
if is_send:
self.setAlignment(Qt.AlignCenter | Qt.AlignRight)
# self.setScaledContents(True)
def set_image(self, pixmap):
# 计算调整后的大小
adjusted_width = min(pixmap.width(), self.max_width)
adjusted_height = min(pixmap.height(), self.max_height)
self.setPixmap(pixmap.scaled(adjusted_width, adjusted_height, Qt.KeepAspectRatio))
# 调整QLabel的大小以适应图片的宽高但不超过最大宽高
# self.setFixedSize(adjusted_width, adjusted_height)
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton: # 左键按下
print('打开图像', self.image_path)
self.open_image_thread = OpenImageThread(self.image_path)
self.open_image_thread.start()
class BubbleMessage(QWidget):
def __init__(self, str_content, avatar, Type, is_send=False, display_name=None, parent=None):
super().__init__(parent)
self.isSend = is_send
# self.set
self.setStyleSheet(
'''
border:none;
'''
)
layout = QHBoxLayout()
layout.setSpacing(0)
layout.setContentsMargins(0, 5, 5, 5)
# self.resize(QSize(200, 50))
self.avatar = Avatar(avatar)
triangle = Triangle(Type, is_send, (0, 0))
if Type == MessageType.Text:
self.message = TextMessage(str_content, is_send)
# self.message.setMaximumWidth(int(self.width() * 0.6))
elif Type == MessageType.Image:
self.message = ImageMessage(str_content, is_send)
else:
raise ValueError("未知的消息类型")
if display_name:
triangle = Triangle(Type, is_send, (0, 10))
label_name = QLabel(display_name, self)
label_name.setFont(QFont('微软雅黑', 10))
if is_send:
label_name.setAlignment(Qt.AlignRight)
vlayout = QVBoxLayout()
vlayout.setSpacing(0)
if is_send:
vlayout.addWidget(label_name, 0, Qt.AlignTop | Qt.AlignRight)
vlayout.addWidget(self.message, 0, Qt.AlignTop | Qt.AlignRight)
else:
vlayout.addWidget(label_name)
vlayout.addWidget(self.message)
self.spacerItem = QSpacerItem(45 + 6, 45, QSizePolicy.Expanding, QSizePolicy.Minimum)
if is_send:
layout.addItem(self.spacerItem)
if display_name:
layout.addLayout(vlayout, 1)
else:
layout.addWidget(self.message, 1)
layout.addWidget(triangle, 0, Qt.AlignTop | Qt.AlignLeft)
layout.addWidget(self.avatar, 0, Qt.AlignTop | Qt.AlignLeft)
else:
layout.addWidget(self.avatar, 0, Qt.AlignTop | Qt.AlignRight)
layout.addWidget(triangle, 0, Qt.AlignTop | Qt.AlignRight)
if display_name:
layout.addLayout(vlayout, 1)
else:
layout.addWidget(self.message, 1)
layout.addItem(self.spacerItem)
self.setLayout(layout)
class ScrollAreaContent(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.adjustSize()
class ScrollArea(QScrollArea):
def __init__(self, parent=None):
super().__init__(parent)
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setStyleSheet(
'''
border:none;
'''
)
class ChatWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(500, 200)
layout = QVBoxLayout()
layout.setSpacing(0)
self.adjustSize()
# 生成滚动区域
self.scrollArea = ScrollArea(self)
scrollBar = ScrollBar()
self.scrollArea.setVerticalScrollBar(scrollBar)
# 生成滚动区域的内容部署层部件
self.scrollAreaWidgetContents = ScrollAreaContent(self.scrollArea)
self.scrollAreaWidgetContents.setMinimumSize(50, 100)
# 设置滚动区域的内容部署部件为前面生成的内容部署层部件
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
layout.addWidget(self.scrollArea)
self.layout0 = QVBoxLayout()
self.layout0.setSpacing(0)
self.scrollAreaWidgetContents.setLayout(self.layout0)
self.setLayout(layout)
def add_message_item(self, bubble_message, index=1):
if index:
self.layout0.addWidget(bubble_message)
else:
self.layout0.insertWidget(0, bubble_message)
# self.set_scroll_bar_last()
def set_scroll_bar_last(self):
self.scrollArea.verticalScrollBar().setValue(
self.scrollArea.verticalScrollBar().maximum()
)
def set_scroll_bar_value(self, val):
self.verticalScrollBar().setValue(val)
def verticalScrollBar(self):
return self.scrollArea.verticalScrollBar()
def update(self) -> None:
super().update()
self.scrollAreaWidgetContents.adjustSize()
self.scrollArea.update()
# self.scrollArea.repaint()
# self.verticalScrollBar().setMaximum(self.scrollAreaWidgetContents.height())

View File

@@ -0,0 +1,78 @@
import time
from datetime import datetime, timedelta
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, \
QToolButton
from app.ui.Icon import Icon
class CalendarDialog(QDialog):
selected_date_signal = pyqtSignal(int)
def __init__(self, date_range=None, parent=None):
"""
@param date_range: tuple[Union[QDate, datetime.date],Union[QDate, datetime.date]] #限定的可选择范围
@param parent:
"""
super().__init__(parent)
self.setWindowTitle('选择日期')
self.calendar = QCalendarWidget(self)
self.calendar.clicked.connect(self.onDateChanged)
prev_btn = self.calendar.findChild(QToolButton, "qt_calendar_prevmonth")
prev_btn.setIcon(Icon.Arrow_left_Icon)
next_btn = self.calendar.findChild(QToolButton, "qt_calendar_nextmonth")
next_btn.setIcon(Icon.Arrow_right_Icon)
self.date_range = date_range
if date_range:
self.calendar.setDateRange(*date_range)
# 从第一天开始,依次添加日期到列表,直到该月的最后一天
current_date = date_range[1]
while (current_date + timedelta(days=1)).month == date_range[1].month:
current_date += timedelta(days=1)
range_format = self.calendar.dateTextFormat(current_date)
range_format.setForeground(Qt.gray)
self.calendar.setDateTextFormat(current_date, range_format)
# 从第一天开始,依次添加日期到列表,直到该月的最后一天
current_date = date_range[0]
while (current_date - timedelta(days=1)).month == date_range[0].month:
current_date -= timedelta(days=1)
range_format = self.calendar.dateTextFormat(current_date)
range_format.setForeground(Qt.gray)
self.calendar.setDateTextFormat(current_date, range_format)
layout = QVBoxLayout(self)
layout.addWidget(self.calendar)
self.setLayout(layout)
def set_start_date(self):
if self.date_range:
self.calendar.setCurrentPage(self.date_range[0].year, self.date_range[0].month)
def set_end_date(self):
if self.date_range:
self.calendar.setCurrentPage(self.date_range[1].year, self.date_range[1].month)
def onDateChanged(self):
# 获取选择的日期
selected_date = self.calendar.selectedDate()
s_t = time.strptime(selected_date.toString("yyyy-MM-dd"), "%Y-%m-%d") # 返回元祖
mkt = int(time.mktime(s_t))
timestamp = mkt
self.selected_date_signal.emit(timestamp)
print("Selected Date:", selected_date.toString("yyyy-MM-dd"), timestamp)
self.close()
if __name__ == '__main__':
import sys
from datetime import datetime, timedelta
app = QApplication(sys.argv)
# 设置日期范围
start_date = datetime(2024, 1, 5)
end_date = datetime(2024, 1, 9)
date_range = (start_date.date(), end_date.date())
ex = CalendarDialog(date_range=date_range)
ex.show()
sys.exit(app.exec_())

View File

@@ -0,0 +1,104 @@
import sys
from PyQt5.Qt import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from .CAvatar import CAvatar
Stylesheet = """
QWidget{
background: rgb(238,244,249);
}
"""
Stylesheet_hover = """
QWidget,QLabel{
background: rgb(230, 235, 240);
}
"""
Stylesheet_clicked = """
QWidget,QLabel{
background: rgb(230, 235, 240);
}
"""
class QListWidgetItemWidget(QWidget):
def __init__(self):
super().__init__()
self.is_selected = False
def leaveEvent(self, e): # 鼠标离开label
if self.is_selected:
return
self.setStyleSheet(Stylesheet)
def enterEvent(self, e): # 鼠标移入label
self.setStyleSheet(Stylesheet_hover)
# 自定义的item 继承自QListWidgetItem
class ContactQListWidgetItem(QListWidgetItem):
def __init__(self, name, url, img_bytes=None):
super().__init__()
# 自定义item中的widget 用来显示自定义的内容
self.widget = QListWidgetItemWidget()
# 用来显示name
self.nameLabel = QLabel(self.widget)
self.nameLabel.setText(name)
# 用来显示avator(图像)
self.avatorLabel = CAvatar(parent=self.widget, shape=CAvatar.Rectangle, size=QSize(60, 60),
url=url, img_bytes=img_bytes)
# 设置布局用来对nameLabel和avatorLabel进行布局
hbox = QHBoxLayout()
hbox.addWidget(self.avatorLabel)
hbox.addWidget(self.nameLabel)
hbox.addStretch(1)
# 设置widget的布局
self.widget.setLayout(hbox)
self.widget.setStyleSheet(Stylesheet)
# 设置自定义的QListWidgetItem的sizeHint不然无法显示
self.setSizeHint(self.widget.sizeHint())
def select(self):
"""
设置选择后的事件
@return:
"""
self.widget.is_selected = True
self.widget.setStyleSheet(Stylesheet_clicked)
def dis_select(self):
"""
设置取消选择的事件
@return:
"""
self.widget.is_selected = False
self.widget.setStyleSheet(Stylesheet)
if __name__ == "__main__":
app = QApplication(sys.argv)
# 主窗口
w = QWidget()
w.setWindowTitle("QListWindow")
# 新建QListWidget
listWidget = QListWidget(w)
listWidget.resize(300, 300)
# 新建两个自定义的QListWidgetItem(customQListWidgetItem)
item1 = ContactQListWidgetItem("鲤鱼王", "liyuwang.jpg")
item2 = ContactQListWidgetItem("可达鸭", "kedaya.jpg")
# 在listWidget中加入两个自定义的item
listWidget.addItem(item1)
listWidget.setItemWidget(item1, item1.widget)
listWidget.addItem(item2)
listWidget.setItemWidget(item2, item2.widget)
# 绑定点击槽函数 点击显示对应item中的name
listWidget.itemClicked.connect(lambda item: print(item.nameLabel.text()))
w.show()
sys.exit(app.exec_())

View File

@@ -0,0 +1,127 @@
import sys
from PyQt5.Qt import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
try:
from .CAvatar import CAvatar
except:
from CAvatar import CAvatar
Stylesheet = """
QWidget{
background: rgb(238,244,249);
}
"""
Stylesheet_hover = """
QWidget,QLabel{
background: rgb(230, 235, 240);
}
"""
Stylesheet_clicked = """
QWidget,QLabel{
background: rgb(230, 235, 240);
}
"""
class QListWidgetItemWidget(QWidget):
def __init__(self):
super().__init__()
self.is_selected = False
def leaveEvent(self, e): # 鼠标离开label
if self.is_selected:
return
self.setStyleSheet(Stylesheet)
def enterEvent(self, e): # 鼠标移入label
self.setStyleSheet(Stylesheet_hover)
# 自定义的item 继承自QListWidgetItem
class ContactQListWidgetItem(QListWidgetItem):
def __init__(self, name, url, img_bytes=None):
super().__init__()
self.is_select = False
# 自定义item中的widget 用来显示自定义的内容
self.widget = QListWidgetItemWidget()
# 用来显示name
self.nameLabel = QLabel(self.widget)
self.nameLabel.setText(name)
# 用来显示avator(图像)
self.avatorLabel = CAvatar(parent=self.widget, shape=CAvatar.Rectangle, size=QSize(30, 30),
url=url, img_bytes=img_bytes)
# 设置布局用来对nameLabel和avatorLabel进行布局
hbox = QHBoxLayout(self.widget)
self.checkBox = QCheckBox(self.widget)
self.checkBox.clicked.connect(self.select)
hbox.addWidget(self.checkBox)
hbox.addWidget(self.avatorLabel)
hbox.addWidget(self.nameLabel)
hbox.addStretch(1)
# 设置widget的布局
self.widget.setLayout(hbox)
self.widget.setStyleSheet(Stylesheet)
# 设置自定义的QListWidgetItem的sizeHint不然无法显示
self.setSizeHint(self.widget.sizeHint())
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
def select(self):
"""
设置选择后的事件
@return:
"""
self.widget.is_selected = True
self.is_select = not self.is_select
# print('选择',self.is_select)
self.checkBox.setChecked(self.is_select)
# self.widget.setStyleSheet(Stylesheet_clicked)
def force_select(self):
self.is_select = True
self.checkBox.setChecked(self.is_select)
def force_dis_select(self):
self.is_select = False
self.checkBox.setChecked(self.is_select)
def dis_select(self):
"""
设置取消选择的事件
@return:
"""
self.widget.is_selected = False
self.widget.setStyleSheet(Stylesheet)
if __name__ == "__main__":
app = QApplication(sys.argv)
# 主窗口
w = QWidget()
w.setWindowTitle("QListWindow")
# 新建QListWidget
listWidget = QListWidget(w)
listWidget.resize(300, 300)
# 新建两个自定义的QListWidgetItem(customQListWidgetItem)
item1 = ContactQListWidgetItem("鲤鱼王", "liyuwang.jpg")
item2 = ContactQListWidgetItem("可达鸭", "kedaya.jpg")
# 在listWidget中加入两个自定义的item
listWidget.addItem(item1)
listWidget.setItemWidget(item1, item1.widget)
listWidget.addItem(item2)
listWidget.setItemWidget(item2, item2.widget)
# 绑定点击槽函数 点击显示对应item中的name
listWidget.itemClicked.connect(lambda item: item.select())
w.show()
sys.exit(app.exec_())

View File

@@ -0,0 +1,39 @@
from PyQt5 import QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class PromptBar(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
def paintEvent(self, e): # 绘图事件
qp = QPainter()
qp.begin(self)
self.drawRectangles1(qp) # 绘制线条矩形
self.drawRectangles2(qp) # 绘制填充矩形
self.drawRectangles3(qp) # 绘制线条+填充矩形
self.drawRectangles4(qp) # 绘制线条矩形2
qp.end()
def drawRectangles1(self, qp): # 绘制填充矩形
qp.setPen(QPen(Qt.black, 2, Qt.SolidLine)) # 颜色、线宽、线性
qp.drawRect(*self.data)
def drawRectangles2(self, qp): # 绘制填充矩形
qp.setPen(QPen(Qt.black, 2, Qt.NoPen))
qp.setBrush(QColor(200, 0, 0))
qp.drawRect(220, 15, 200, 100)
def drawRectangles3(self, qp): # 绘制线条+填充矩形
qp.setPen(QPen(Qt.black, 2, Qt.SolidLine))
qp.setBrush(QColor(200, 0, 0))
qp.drawRect(430, 15, 200, 100)
def drawRectangles4(self, qp): # 绘制线条矩形2
path = QtGui.QPainterPath()
qp.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
qp.setBrush(QColor(0, 0, 0, 0)) # 设置画刷颜色透明
path.addRect(100, 200, 200, 100)
qp.drawPath(path)

View File

@@ -0,0 +1,48 @@
from PyQt5.QtWidgets import QScrollBar
class ScrollBar(QScrollBar):
def __init__(self):
super().__init__()
self.setStyleSheet(
'''
QScrollBar:vertical {
border-width: 0px;
border: none;
background:rgba(133, 135, 138, 0);
width:4px;
margin: 0px 0px 0px 0px;
}
QScrollBar::handle:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgb(133, 135, 138), stop: 0.5 rgb(133, 135, 138), stop:1 rgb(133, 135, 138));
min-height: 20px;
max-height: 20px;
margin: 0 0px 0 0px;
border-radius: 2px;
}
QScrollBar::add-line:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgba(133, 135, 138, 0), stop: 0.5 rgba(133, 135, 138, 0), stop:1 rgba(133, 135, 138, 0));
height: 0px;
border: none;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 rgba(133, 135, 138, 0), stop: 0.5 rgba(133, 135, 138, 0), stop:1 rgba(133, 135, 138, 0));
height: 0 px;
border: none;
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::sub-page:vertical {
background: rgba(133, 135, 138, 0);
}
QScrollBar::add-page:vertical {
background: rgba(133, 135, 138, 0);
}
'''
)