WeChatMsg/app/components/bubble_message.py

296 lines
10 KiB
Python
Raw Normal View History

2023-11-17 15:31:21 +08:00
from PIL import Image
from PyQt5 import QtGui
from PyQt5.QtGui import QPainter, QFont, QColor, QPixmap, QPolygon
2023-11-17 17:20:13 +08:00
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QSizePolicy, QVBoxLayout, QSpacerItem, \
QScrollArea, QScrollBar
from PyQt5.QtCore import QSize, pyqtSignal, Qt, QThread
2023-11-16 19:53:23 +08:00
2023-11-17 15:31:21 +08:00
class TextMessage(QLabel):
heightSingal = pyqtSignal(int)
2023-11-16 19:53:23 +08:00
2023-11-17 15:31:21 +08:00
def __init__(self, text, is_send=False, parent=None):
super(TextMessage, self).__init__(text, parent)
self.setFont(QFont('SimSun', 15))
self.setWordWrap(True)
# self.adjustSize()
self.setMaximumWidth(800)
self.setMinimumWidth(100)
self.setMinimumHeight(10)
# self.resize(QSize(100,40))
self.setTextInteractionFlags(Qt.TextSelectableByMouse)
2023-11-16 19:53:23 +08:00
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
2023-11-17 15:31:21 +08:00
# self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
if is_send:
self.setAlignment(Qt.AlignCenter | Qt.AlignRight)
self.setStyleSheet(
'''
background-color:white;
border-radius:10px;
border-top: 10px solid white;
border-bottom: 10px solid white;
border-right: 10px solid white;
border-left: 10px solid white;
'''
)
else:
self.setStyleSheet(
'''
background-color:#b2e281;
border-radius:10px;
border-top: 10px solid #b2e281;
border-bottom: 10px solid #b2e281;
border-right: 10px solid #b2e281;
border-left: 10px solid #b2e281;
'''
)
2023-11-16 19:53:23 +08:00
2023-11-17 15:31:21 +08:00
def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
super(TextMessage, self).paintEvent(a0)
2023-11-16 19:53:23 +08:00
2023-11-17 15:31:21 +08:00
class Triangle(QLabel):
def __init__(self, Type, is_send=False, parent=None):
super().__init__(parent)
self.Type = Type
self.is_send = is_send
self.setFixedSize(6, 45)
def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
super(Triangle, self).paintEvent(a0)
if self.Type == 3:
painter = QPainter(self)
triangle = QPolygon()
# print(self.width(), self.height())
if self.is_send:
painter.setPen(QColor('white'))
painter.setBrush(QColor('white'))
triangle.setPoints(0, 20, 0, 35, 6, 25)
else:
painter.setPen(QColor('#b2e281'))
painter.setBrush(QColor('#b2e281'))
triangle.setPoints(0, 25, 6, 20, 6, 35)
painter.drawPolygon(triangle)
2023-11-17 17:20:13 +08:00
class Notice(QLabel):
def __init__(self, text, type_=3, parent=None):
super().__init__(text, parent)
self.type_ = type_
self.setFont(QFont('微软雅黑', 12))
self.setWordWrap(True)
self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setAlignment(Qt.AlignCenter)
2023-11-17 15:31:21 +08:00
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)
self.setMaximumWidth(45)
self.setMaximumHeight(45)
2023-11-17 17:20:13 +08:00
class OpenImageThread(QThread):
def __init__(self, image_path):
super().__init__()
self.image_path = image_path
def run(self) -> None:
image = Image.open(self.image_path)
image.show()
2023-11-17 15:31:21 +08:00
class ImageMessage(QLabel):
def __init__(self, avatar, parent=None):
2023-11-16 19:53:23 +08:00
super().__init__(parent)
2023-11-17 15:31:21 +08:00
self.image_path = './Data/head.jpg'
self.image = QLabel(self)
if isinstance(avatar, str):
self.setPixmap(QPixmap(avatar))
self.image_path = avatar
elif isinstance(avatar, QPixmap):
self.setPixmap(avatar)
self.setMaximumWidth(480)
self.setMaximumHeight(720)
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton: # 左键按下
2023-11-17 17:20:13 +08:00
self.open_image_thread = OpenImageThread(self.image_path)
self.open_image_thread.start()
2023-11-17 15:31:21 +08:00
class BubbleMessage(QWidget):
def __init__(self, str_content, avatar, Type, is_send=False, parent=None):
super().__init__(parent)
self.isSend = is_send
2023-11-17 17:20:13 +08:00
# self.set
self.setStyleSheet(
'''
border:none;
'''
)
2023-11-16 19:53:23 +08:00
layout = QHBoxLayout()
2023-11-17 15:31:21 +08:00
layout.setSpacing(0)
2023-11-17 17:20:13 +08:00
layout.setContentsMargins(0, 5, 5, 5)
2023-11-17 15:31:21 +08:00
self.avatar = Avatar(avatar)
2023-11-17 17:20:13 +08:00
triangle = Triangle(Type, is_send)
2023-11-17 15:31:21 +08:00
if Type == 3:
self.message = TextMessage(str_content, is_send)
else:
self.message = ImageMessage(str_content)
# skin_aio_friend_bubble_pressed.9
'''
border-image:url(./Data/截图222.png) 20 20 20 20;
border-top: 5px transparent;
border-bottom: 5px transparent;
border-right: 5px transparent;
border-left: 5px transparent;
border-radius:10px;
'''
2023-11-17 17:20:13 +08:00
self.spacerItem = QSpacerItem(45 + 6, 45, QSizePolicy.Expanding, QSizePolicy.Minimum)
2023-11-17 15:31:21 +08:00
if is_send:
layout.addItem(self.spacerItem)
2023-11-17 17:20:13 +08:00
layout.addWidget(self.message, 1)
layout.addWidget(triangle, 0, Qt.AlignTop | Qt.AlignLeft)
2023-11-17 15:31:21 +08:00
layout.addWidget(self.avatar, 0, Qt.AlignTop | Qt.AlignLeft)
2023-11-16 19:53:23 +08:00
else:
2023-11-17 15:31:21 +08:00
layout.addWidget(self.avatar, 0, Qt.AlignTop | Qt.AlignRight)
layout.addWidget(triangle, 0, Qt.AlignTop | Qt.AlignRight)
2023-11-17 17:20:13 +08:00
layout.addWidget(self.message, 1)
2023-11-17 15:31:21 +08:00
layout.addItem(self.spacerItem)
2023-11-16 19:53:23 +08:00
self.setLayout(layout)
2023-11-17 17:20:13 +08:00
class ScrollAreaContent(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
# print(self.width(),self.height())
self.setMinimumSize(self.width(), self.height())
class ScrollArea(QScrollArea):
def __init__(self, parent=None):
super().__init__(parent)
self.setWidgetResizable(True)
self.setStyleSheet(
'''
border:none;
'''
)
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
# return
self.widget().setMinimumSize(self.width(), self.widget().height())
self.widget().setMaximumSize(self.width(), self.widget().height())
self.widget().resize(QSize(self.width(), self.widget().height()))
#
class ScrollBar(QScrollBar):
def __init__(self):
super().__init__()
self.setStyleSheet(
'''
QScrollBar:vertical {
border-width: 0px;
border: none;
background:rgba(64, 65, 79, 0);
width:5px;
margin: 0px 0px 0px 0px;
}
QScrollBar::handle:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop: 0 #DDDDDD, stop: 0.5 #DDDDDD, stop:1 #aaaaff);
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(64, 65, 79, 0), stop: 0.5 rgba(64, 65, 79, 0), stop:1 rgba(64, 65, 79, 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(64, 65, 79, 0), stop: 0.5 rgba(64, 65, 79, 0), stop:1 rgba(64, 65, 79, 0));
height: 0 px;
border: none;
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::sub-page:vertical {
background: rgba(64, 65, 79, 0);
}
QScrollBar::add-page:vertical {
background: rgba(64, 65, 79, 0);
}
'''
)
2023-11-17 15:31:21 +08:00
class MyWidget(QWidget):
2023-11-16 19:53:23 +08:00
def __init__(self):
super().__init__()
2023-11-17 17:20:13 +08:00
self.resize(500, 200)
2023-11-16 19:53:23 +08:00
txt = '''在工具中单击边缘可以添加黑点,单击可以删掉黑点,拖动可以调整黑点长度。勾选等选项可以查看内容、缩放等区域右侧可预览不同拉伸情况下的效果,拖动可以调整预览的拉伸比例'''
2023-11-17 15:31:21 +08:00
avatar = 'Data/head.jpg'
bubble_message = BubbleMessage(txt, avatar, Type=3, is_send=False)
2023-11-16 19:53:23 +08:00
layout = QVBoxLayout()
2023-11-17 17:20:13 +08:00
layout.setSpacing(0)
# 生成滚动区域
self.scrollArea = ScrollArea()
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scrollBar = ScrollBar()
self.scrollArea.setVerticalScrollBar(scrollBar)
# self.scrollArea.setGeometry(QRect(9, 9, 261, 211))
# 生成滚动区域的内容部署层部件
self.scrollAreaWidgetContents = ScrollAreaContent()
self.scrollAreaWidgetContents.setMinimumSize(50, 100)
# 设置滚动区域的内容部署部件为前面生成的内容部署层部件
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
layout.addWidget(self.scrollArea)
layout0 = QVBoxLayout()
layout0.setSpacing(0)
self.scrollArea.setLayout(layout0)
self.scrollAreaWidgetContents.setLayout(layout0)
time = Notice("2023-11-17 15:44")
layout0.addWidget(time)
2023-11-17 15:31:21 +08:00
txt = "你说啥"
avatar_2 = 'Data/fg1.png'
bubble_message1 = BubbleMessage(txt, avatar_2, Type=3, is_send=True)
2023-11-17 17:20:13 +08:00
layout0.addWidget(bubble_message)
layout0.addWidget(bubble_message1)
2023-11-17 15:31:21 +08:00
bubble_message2 = BubbleMessage('', avatar_2, Type=3, is_send=True)
2023-11-17 17:20:13 +08:00
layout0.addWidget(bubble_message2)
2023-11-17 15:31:21 +08:00
txt = "我啥都没说"
avatar0 = 'Data/fg1.png'
bubble_message1 = BubbleMessage('Data/fg1.png', avatar, Type=1, is_send=False)
2023-11-17 17:20:13 +08:00
layout0.addWidget(bubble_message1)
self.spacerItem = QSpacerItem(10, 10, QSizePolicy.Minimum, QSizePolicy.Expanding)
layout0.addItem(self.spacerItem)
layout.setStretch(0, 1)
2023-11-16 19:53:23 +08:00
self.setLayout(layout)
2023-11-17 15:31:21 +08:00
if __name__ == '__main__':
app = QApplication([])
widget = MyWidget()
widget.show()
app.exec_()