mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-23 03:22:17 +08:00
commit
2621577b2e
@ -4,13 +4,10 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="84e65474-7da9-466d-baf3-cc88dde3ffdd" name="变更" comment="修复聊天气泡不能更改大小的bug">
|
||||
<list default="true" id="84e65474-7da9-466d-baf3-cc88dde3ffdd" name="变更" comment="新版本更新">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/person.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/person.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/chat/chat_info.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/chat/chat_info.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/mainview.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/mainview.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/pc_decrypt.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/pc_decrypt.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/tool/tool_window.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/tool/tool_window.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/DataBase/micro_msg.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/DataBase/micro_msg.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/readme.md" beforeDir="false" afterPath="$PROJECT_DIR$/readme.md" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -128,27 +125,6 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="chat_info" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/ui_pc/chat" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/ui_pc/chat/chat_info.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="main_pc" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
@ -254,13 +230,34 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/components" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/components/test.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.main_pc" />
|
||||
<item itemvalue="Python.person" />
|
||||
<item itemvalue="Python.bubble_message" />
|
||||
<item itemvalue="Python.chat_info" />
|
||||
<item itemvalue="Python.test" />
|
||||
<item itemvalue="Python.msg" />
|
||||
<item itemvalue="Python.person" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
@ -276,48 +273,6 @@
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1672848140146</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00021" summary="readme">
|
||||
<created>1684598440645</created>
|
||||
<option name="number" value="00021" />
|
||||
<option name="presentableId" value="LOCAL-00021" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684598440645</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00022" summary="readme">
|
||||
<created>1684599002132</created>
|
||||
<option name="number" value="00022" />
|
||||
<option name="presentableId" value="LOCAL-00022" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684599002132</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00023" summary="readme">
|
||||
<created>1684599566617</created>
|
||||
<option name="number" value="00023" />
|
||||
<option name="presentableId" value="LOCAL-00023" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684599566617</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00024" summary="readme">
|
||||
<created>1684599688133</created>
|
||||
<option name="number" value="00024" />
|
||||
<option name="presentableId" value="LOCAL-00024" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684599688133</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00025" summary="readme">
|
||||
<created>1684600483941</created>
|
||||
<option name="number" value="00025" />
|
||||
<option name="presentableId" value="LOCAL-00025" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684600483941</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00026" summary="readme">
|
||||
<created>1684600882947</created>
|
||||
<option name="number" value="00026" />
|
||||
<option name="presentableId" value="LOCAL-00026" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1684600882947</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00027" summary="mainwindows文件修正">
|
||||
<created>1684726034556</created>
|
||||
<option name="number" value="00027" />
|
||||
@ -619,7 +574,49 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700232296923</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="70" />
|
||||
<task id="LOCAL-00070" summary="更改头像显示">
|
||||
<created>1700233361985</created>
|
||||
<option name="number" value="00070" />
|
||||
<option name="presentableId" value="LOCAL-00070" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700233361985</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00071" summary="将自己的wxid设置为配置文件">
|
||||
<created>1700236486745</created>
|
||||
<option name="number" value="00071" />
|
||||
<option name="presentableId" value="LOCAL-00071" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700236486745</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00072" summary="修改聊天记录显示顺序">
|
||||
<created>1700236795662</created>
|
||||
<option name="number" value="00072" />
|
||||
<option name="presentableId" value="LOCAL-00072" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700236795662</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00073" summary="聊天记录从后往前显示">
|
||||
<created>1700279520681</created>
|
||||
<option name="number" value="00073" />
|
||||
<option name="presentableId" value="LOCAL-00073" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700279520681</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00074" summary="聊天消息自适应">
|
||||
<created>1700285158430</created>
|
||||
<option name="number" value="00074" />
|
||||
<option name="presentableId" value="LOCAL-00074" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700285158430</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00075" summary="新版本更新">
|
||||
<created>1700289701717</created>
|
||||
<option name="number" value="00075" />
|
||||
<option name="presentableId" value="LOCAL-00075" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700289701718</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="76" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="UnknownFeatures">
|
||||
@ -655,12 +652,6 @@
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="用stackWidget重写contactUI" />
|
||||
<MESSAGE value="修改联系人视图架构" />
|
||||
<MESSAGE value="加快打开速度" />
|
||||
<MESSAGE value="修改导入路径,方便打包成exe" />
|
||||
<MESSAGE value="修改部分UI" />
|
||||
<MESSAGE value="上传html模板" />
|
||||
<MESSAGE value="增加几个图标" />
|
||||
<MESSAGE value="增加导航按钮效果" />
|
||||
<MESSAGE value="新增PC数据库解密" />
|
||||
@ -680,7 +671,13 @@
|
||||
<MESSAGE value="update readme" />
|
||||
<MESSAGE value="数据库加锁避免多线程访问报错" />
|
||||
<MESSAGE value="修复聊天气泡不能更改大小的bug" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="修复聊天气泡不能更改大小的bug" />
|
||||
<MESSAGE value="更改头像显示" />
|
||||
<MESSAGE value="将自己的wxid设置为配置文件" />
|
||||
<MESSAGE value="修改聊天记录显示顺序" />
|
||||
<MESSAGE value="聊天记录从后往前显示" />
|
||||
<MESSAGE value="聊天消息自适应" />
|
||||
<MESSAGE value="新版本更新" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="新版本更新" />
|
||||
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
</component>
|
||||
@ -704,17 +701,17 @@
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>101</line>
|
||||
<line>100</line>
|
||||
<option name="timeStamp" value="10" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>99</line>
|
||||
<line>98</line>
|
||||
<option name="timeStamp" value="11" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>100</line>
|
||||
<line>99</line>
|
||||
<option name="timeStamp" value="12" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
|
@ -1,7 +1,8 @@
|
||||
import os.path
|
||||
import sqlite3
|
||||
import time
|
||||
import threading
|
||||
|
||||
lock = threading.Lock()
|
||||
DB = None
|
||||
cursor = None
|
||||
micromsg_path = "./app/Database/Msg/MicroMsg.db"
|
||||
@ -27,23 +28,16 @@ def is_database_exist():
|
||||
|
||||
def get_contact():
|
||||
try:
|
||||
lock.acquire(True)
|
||||
sql = '''select UserName,Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl.bigHeadImgUrl
|
||||
from Contact inner join ContactHeadImgUrl on Contact.UserName = ContactHeadImgUrl.usrName
|
||||
where Type=3 and Alias is not null
|
||||
order by PYInitial
|
||||
limit 30
|
||||
'''
|
||||
cursor.execute(sql)
|
||||
result = cursor.fetchall()
|
||||
except:
|
||||
time.sleep(0.2)
|
||||
sql = '''select UserName,Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl.bigHeadImgUrl
|
||||
from Contact inner join ContactHeadImgUrl on Contact.UserName = ContactHeadImgUrl.usrName
|
||||
where Type=3 and Alias is not null
|
||||
where Type%2=1 and Alias is not null
|
||||
order by PYInitial
|
||||
'''
|
||||
cursor.execute(sql)
|
||||
result = cursor.fetchall()
|
||||
finally:
|
||||
lock.release()
|
||||
# DB.commit()
|
||||
return result
|
||||
|
||||
|
@ -2,6 +2,7 @@ import os.path
|
||||
import re
|
||||
import sqlite3
|
||||
import threading
|
||||
from pprint import pprint
|
||||
|
||||
DB = []
|
||||
cursor = []
|
||||
@ -56,20 +57,20 @@ def get_messages(username_):
|
||||
return result
|
||||
|
||||
|
||||
def get_message_by_num(username_, n):
|
||||
def get_message_by_num(username_, local_id):
|
||||
sql = '''
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime
|
||||
from MSG
|
||||
where StrTalker=?
|
||||
order by CreateTime
|
||||
limit 10
|
||||
where StrTalker = ? and localId < ?
|
||||
order by CreateTime desc
|
||||
limit 30
|
||||
'''
|
||||
result = []
|
||||
try:
|
||||
lock.acquire(True)
|
||||
for cur in cursor:
|
||||
cur = cursor[-1]
|
||||
cur.execute(sql, [username_])
|
||||
cur.execute(sql, [username_, local_id])
|
||||
result_ = cur.fetchall()
|
||||
result += result_
|
||||
return result_
|
||||
@ -92,5 +93,8 @@ if __name__ == '__main__':
|
||||
# result = get_messages(username)
|
||||
# pprint(result)
|
||||
# pprint(len(result))
|
||||
result = get_message_by_num('wxid_0o18ef858vnu22', 0)
|
||||
result = get_message_by_num('wxid_0o18ef858vnu22', 9999999)
|
||||
print(result)
|
||||
print(result[-1][0])
|
||||
local_id = result[-1][0]
|
||||
pprint(get_message_by_num('wxid_0o18ef858vnu22', local_id))
|
||||
|
@ -1,6 +1,6 @@
|
||||
from PIL import Image
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5.QtCore import QSize, pyqtSignal, Qt, QThread
|
||||
from PyQt5.QtCore import QSize, pyqtSignal, Qt, QThread, QTimer
|
||||
from PyQt5.QtGui import QPainter, QFont, QColor, QPixmap, QPolygon
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QSizePolicy, QVBoxLayout, QSpacerItem, \
|
||||
QScrollArea, QScrollBar
|
||||
@ -140,6 +140,7 @@ class BubbleMessage(QWidget):
|
||||
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)
|
||||
if Type == 1:
|
||||
@ -173,35 +174,20 @@ class BubbleMessage(QWidget):
|
||||
class ScrollAreaContent(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
# self.setStyleSheet(
|
||||
# '''
|
||||
# background-color:rgb(127,127,127);
|
||||
# '''
|
||||
# )
|
||||
|
||||
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
|
||||
# print(self.width(),self.height())
|
||||
self.setMinimumSize(self.width(), self.height())
|
||||
self.adjustSize()
|
||||
|
||||
|
||||
class ScrollArea(QScrollArea):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWidgetResizable(True)
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
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):
|
||||
@ -250,70 +236,103 @@ class ScrollBar(QScrollBar):
|
||||
)
|
||||
|
||||
|
||||
class MyWidget(QWidget):
|
||||
class ChatWidget(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.resize(500, 200)
|
||||
txt = '''在工具中单击边缘可以添加黑点,单击可以删掉黑点,拖动可以调整黑点长度。勾选等选项可以查看内容、缩放等区域右侧可预览不同拉伸情况下的效果,拖动可以调整预览的拉伸比例'''
|
||||
avatar = '../data/icons/default_avatar.svg'
|
||||
bubble_message = BubbleMessage(txt, avatar, Type=1, is_send=False)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.setSpacing(0)
|
||||
|
||||
self.adjustSize()
|
||||
# 生成滚动区域
|
||||
self.scrollArea = ScrollArea()
|
||||
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.scrollArea = ScrollArea(self)
|
||||
scrollBar = ScrollBar()
|
||||
self.scrollArea.setVerticalScrollBar(scrollBar)
|
||||
# self.scrollArea.setGeometry(QRect(9, 9, 261, 211))
|
||||
# 生成滚动区域的内容部署层部件
|
||||
self.scrollAreaWidgetContents = ScrollAreaContent()
|
||||
self.scrollAreaWidgetContents = ScrollAreaContent(self.scrollArea)
|
||||
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)
|
||||
txt = "你说啥"
|
||||
avatar_2 = '../data/icons/default_avatar.svg'
|
||||
bubble_message1 = BubbleMessage(txt, avatar_2, Type=1, is_send=True)
|
||||
layout0.addWidget(bubble_message)
|
||||
layout0.addWidget(bubble_message1)
|
||||
|
||||
bubble_message2 = BubbleMessage('', avatar_2, Type=1, is_send=True)
|
||||
layout0.addWidget(bubble_message2)
|
||||
txt = "我啥都没说"
|
||||
avatar0 = 'Data/fg1.png'
|
||||
bubble_message1 = BubbleMessage("D:\Project\Python\PyQt-master\QLabel\Data\\fg1.png", avatar, Type=3,
|
||||
is_send=False)
|
||||
layout0.addWidget(bubble_message1)
|
||||
|
||||
self.spacerItem = QSpacerItem(10, 10, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
layout0.addItem(self.spacerItem)
|
||||
# layout.setStretch(0, 1)
|
||||
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())
|
||||
|
||||
|
||||
class Test(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
layout = QVBoxLayout()
|
||||
self.resize(500, 600)
|
||||
w1 = MyWidget()
|
||||
self.w1 = ChatWidget()
|
||||
bm1 = BubbleMessage(
|
||||
'你好啊噜啦噜啦嘞绿噜啦噜啦嘞绿绿噜啦噜啦嘞绿绿绿噜啦噜啦嘞绿绿绿绿',
|
||||
"D:\Project\Python\PyQt-master\QLabel\Data\\fg1.png",
|
||||
Type=1,
|
||||
)
|
||||
self.w1.add_message_item(bm1)
|
||||
self.w1.verticalScrollBar().valueChanged.connect(self.value)
|
||||
for i in range(10):
|
||||
txt = '''在工具中单击边缘可以添加黑点,单击可以删掉黑点,拖动可以调整黑点长度。勾选等选项可以查看内容、缩放等区域右侧可预览不同拉伸情况下的效果,拖动可以调整预览的拉伸比例'''
|
||||
avatar = '../data/icons/default_avatar.svg'
|
||||
bubble_message = BubbleMessage(txt, avatar, Type=1, is_send=False)
|
||||
# print(bubble_message.height(), '高度')
|
||||
self.w1.add_message_item(bubble_message, 0)
|
||||
print('滚动条最大值', self.w1.verticalScrollBar().maximum())
|
||||
w2 = QLabel("nihao")
|
||||
layout.addWidget(w1)
|
||||
layout.addWidget(self.w1)
|
||||
layout.addWidget(w2)
|
||||
self.setLayout(layout)
|
||||
# 使用 QTimer 延迟更新滚动条
|
||||
QTimer.singleShot(0, lambda: self.w1.update())
|
||||
|
||||
print('滚动条最大值001', self.w1.verticalScrollBar().value())
|
||||
self.w1.verticalScrollBar().setValue(100)
|
||||
# self.w1.update()
|
||||
|
||||
def value(self, val):
|
||||
print('pos:', val)
|
||||
print('滚动条最大值', self.w1.verticalScrollBar().maximum())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication([])
|
||||
widget = Test()
|
||||
widget.w1.update()
|
||||
# widget = MyWidget()
|
||||
widget.w1.verticalScrollBar().setValue(200)
|
||||
print('滚动条最大值002', widget.w1.verticalScrollBar().maximum())
|
||||
widget.show()
|
||||
# QThread.sleep(2)
|
||||
widget.w1.verticalScrollBar().setValue(200)
|
||||
# widget.w1.verticalScrollBar().setValue(200)
|
||||
# widget.w1.verticalScrollBar().setValue(200)
|
||||
|
||||
app.exec_()
|
||||
|
@ -1,2 +1,7 @@
|
||||
version = '0.2.1'
|
||||
version = '0.2.2'
|
||||
contact = '474379264'
|
||||
description = [
|
||||
'1. 支持获取个人信息\n',
|
||||
'2. 支持显示聊天界面\n',
|
||||
'3. 支持导出scv格式的聊天记录\n',
|
||||
]
|
||||
|
@ -64,7 +64,6 @@ class MePC:
|
||||
self.avatar.loadFromData(img_bytes, format='PNG')
|
||||
else:
|
||||
self.avatar.loadFromData(img_bytes, format='jfif')
|
||||
self.avatar = QPixmap()
|
||||
|
||||
|
||||
class ContactPC:
|
||||
|
@ -1,14 +1,16 @@
|
||||
from PyQt5.QtCore import QThread, pyqtSignal, Qt
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSpacerItem, QSizePolicy, QLabel, QHBoxLayout
|
||||
from PyQt5.QtCore import QThread, pyqtSignal
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout
|
||||
|
||||
from app.DataBase import msg
|
||||
from app.components.bubble_message import BubbleMessage, ScrollBar, ScrollArea, ScrollAreaContent
|
||||
from app.components.bubble_message import BubbleMessage, ChatWidget, Notice
|
||||
from app.person import MePC
|
||||
|
||||
|
||||
class ChatInfo(QWidget):
|
||||
def __init__(self, contact, parent=None):
|
||||
super().__init__(parent)
|
||||
self.last_timestamp = 0
|
||||
self.last_pos = 0
|
||||
self.contact = contact
|
||||
|
||||
self.init_ui()
|
||||
@ -22,41 +24,69 @@ class ChatInfo(QWidget):
|
||||
|
||||
self.vBoxLayout = QVBoxLayout()
|
||||
self.vBoxLayout.setSpacing(0)
|
||||
# self.vBoxLayout.addLayout(self.hBoxLayout)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout)
|
||||
|
||||
self.scrollArea = ScrollArea()
|
||||
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
scrollBar = ScrollBar()
|
||||
self.scrollArea.setVerticalScrollBar(scrollBar)
|
||||
|
||||
self.scrollAreaWidgetContents = ScrollAreaContent()
|
||||
self.scrollAreaWidgetContents.setMinimumSize(200, 10000)
|
||||
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
|
||||
|
||||
self.vBoxLayout.addWidget(self.scrollArea)
|
||||
self.scroolAreaLayout = QVBoxLayout()
|
||||
self.scroolAreaLayout.setSpacing(0)
|
||||
self.scrollAreaWidgetContents.setLayout(self.scroolAreaLayout)
|
||||
self.chat_window = ChatWidget()
|
||||
self.chat_window.scrollArea.verticalScrollBar().valueChanged.connect(self.verticalScrollBar)
|
||||
self.vBoxLayout.addWidget(self.chat_window)
|
||||
self.setLayout(self.vBoxLayout)
|
||||
|
||||
def show_chats(self):
|
||||
self.show_chat_thread = ShowChatThread(self.contact)
|
||||
self.show_chat_thread.showSingal.connect(self.show_chat)
|
||||
self.show_chat_thread.showSingal.connect(self.add_message)
|
||||
self.show_chat_thread.finishSingal.connect(self.show_finish)
|
||||
self.show_chat_thread.start()
|
||||
|
||||
def show_finish(self, ok):
|
||||
self.spacerItem = QSpacerItem(10, 10, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
self.scroolAreaLayout.addItem(self.spacerItem)
|
||||
self.setLayout(self.vBoxLayout)
|
||||
self.setScrollBarPos()
|
||||
|
||||
def show_chat(self, message):
|
||||
def verticalScrollBar(self, pos):
|
||||
"""
|
||||
滚动条到0之后自动更新聊天记录
|
||||
:param pos:
|
||||
:return:
|
||||
"""
|
||||
# print(pos)
|
||||
if pos > 0:
|
||||
return
|
||||
|
||||
# 记录当前滚动条最大值
|
||||
self.last_pos = self.chat_window.verticalScrollBar().maximum()
|
||||
self.update_history_messages()
|
||||
|
||||
def update_history_messages(self):
|
||||
self.show_chat_thread.start()
|
||||
|
||||
def setScrollBarPos(self):
|
||||
"""
|
||||
将滚动条位置设置为上次看到的地方
|
||||
:param pos:
|
||||
:return:
|
||||
"""
|
||||
self.chat_window.update()
|
||||
self.chat_window.show()
|
||||
pos = self.chat_window.verticalScrollBar().maximum() - self.last_pos
|
||||
self.chat_window.set_scroll_bar_value(pos)
|
||||
|
||||
def is_5_min(self, timestamp):
|
||||
if abs(timestamp - self.last_timestamp) > 300:
|
||||
self.last_timestamp = timestamp
|
||||
return True
|
||||
return False
|
||||
|
||||
def add_message(self, message):
|
||||
try:
|
||||
type_ = message[2]
|
||||
str_content = message[7]
|
||||
str_time = message[8]
|
||||
# print(type_, type(type_))
|
||||
is_send = message[4]
|
||||
avatar = MePC().avatar if is_send else self.contact.avatar
|
||||
timestamp = message[5]
|
||||
if type_ == 1:
|
||||
str_content = message[7]
|
||||
if self.is_5_min(timestamp):
|
||||
time_message = Notice(str_time)
|
||||
self.chat_window.add_message_item(time_message, 0)
|
||||
bubble_message = BubbleMessage(
|
||||
str_content,
|
||||
avatar,
|
||||
@ -64,7 +94,8 @@ class ChatInfo(QWidget):
|
||||
is_send
|
||||
)
|
||||
# print(str_content)
|
||||
self.scroolAreaLayout.addWidget(bubble_message)
|
||||
# self.scroolAreaLayout.addWidget(bubble_message)
|
||||
self.chat_window.add_message_item(bubble_message, 0)
|
||||
except:
|
||||
print(message)
|
||||
|
||||
@ -72,14 +103,19 @@ class ChatInfo(QWidget):
|
||||
class ShowChatThread(QThread):
|
||||
showSingal = pyqtSignal(tuple)
|
||||
finishSingal = pyqtSignal(int)
|
||||
msg_id = 0
|
||||
|
||||
# heightSingal = pyqtSignal(int)
|
||||
def __init__(self, contact):
|
||||
super().__init__()
|
||||
self.last_message_id = 9999999
|
||||
self.wxid = contact.wxid
|
||||
|
||||
def run(self) -> None:
|
||||
messages = msg.get_message_by_num(self.wxid, 0)
|
||||
messages = msg.get_message_by_num(self.wxid, self.last_message_id)
|
||||
if messages:
|
||||
self.last_message_id = messages[-1][0]
|
||||
for message in messages:
|
||||
self.showSingal.emit(message)
|
||||
self.msg_id += 1
|
||||
self.finishSingal.emit(1)
|
||||
|
@ -46,6 +46,8 @@ HistoryPanel::item:hover {
|
||||
|
||||
|
||||
class ChatWindow(QWidget, Ui_Form):
|
||||
load_finish_signal = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.show_thread = None
|
||||
@ -74,23 +76,29 @@ class ChatWindow(QWidget, Ui_Form):
|
||||
return
|
||||
self.show_thread = ShowContactThread()
|
||||
self.show_thread.showSingal.connect(self.show_chat)
|
||||
self.show_thread.load_finish_signal.connect(self.stop_loading)
|
||||
self.show_thread.start()
|
||||
self.ok_flag = True
|
||||
|
||||
def show_chat(self, contact):
|
||||
contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl, contact.smallHeadImgBLOG)
|
||||
contact_item = ContactQListWidgetItem(contact.remark, contact.smallHeadImgUrl, contact.smallHeadImgBLOG)
|
||||
self.listWidget.addItem(contact_item)
|
||||
self.listWidget.setItemWidget(contact_item, contact_item.widget)
|
||||
chat_info_window = ChatInfo(contact)
|
||||
self.stackedWidget.addWidget(chat_info_window)
|
||||
|
||||
def setCurrentIndex(self, row):
|
||||
print(row)
|
||||
# print(row)
|
||||
self.stackedWidget.setCurrentIndex(row)
|
||||
|
||||
def stop_loading(self, a0):
|
||||
# self.label.setVisible(False)
|
||||
self.load_finish_signal.emit(True)
|
||||
|
||||
|
||||
class ShowContactThread(QThread):
|
||||
showSingal = pyqtSignal(ContactPC)
|
||||
load_finish_signal = pyqtSignal(bool)
|
||||
|
||||
# heightSingal = pyqtSignal(int)
|
||||
def __init__(self):
|
||||
@ -113,3 +121,4 @@ class ShowContactThread(QThread):
|
||||
contact.set_avatar(contact.smallHeadImgBLOG)
|
||||
self.showSingal.emit(contact)
|
||||
# pprint(contact.__dict__)
|
||||
self.load_finish_signal.emit(True)
|
||||
|
@ -46,6 +46,8 @@ HistoryPanel::item:hover {
|
||||
|
||||
|
||||
class ContactWindow(QWidget, Ui_Form):
|
||||
load_finish_signal = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.show_thread = None
|
||||
@ -73,23 +75,25 @@ class ContactWindow(QWidget, Ui_Form):
|
||||
return
|
||||
self.show_thread = ShowContactThread()
|
||||
self.show_thread.showSingal.connect(self.show_contact)
|
||||
self.show_thread.load_finish_signal.connect(self.load_finish_signal)
|
||||
self.show_thread.start()
|
||||
self.ok_flag = True
|
||||
|
||||
def show_contact(self, contact):
|
||||
contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl, contact.smallHeadImgBLOG)
|
||||
contact_item = ContactQListWidgetItem(contact.remark, contact.smallHeadImgUrl, contact.smallHeadImgBLOG)
|
||||
self.listWidget.addItem(contact_item)
|
||||
self.listWidget.setItemWidget(contact_item, contact_item.widget)
|
||||
contact_info_window = ContactInfo(contact)
|
||||
self.stackedWidget.addWidget(contact_info_window)
|
||||
|
||||
def setCurrentIndex(self, row):
|
||||
print(row)
|
||||
# print(row)
|
||||
self.stackedWidget.setCurrentIndex(row)
|
||||
|
||||
|
||||
class ShowContactThread(QThread):
|
||||
showSingal = pyqtSignal(ContactPC)
|
||||
load_finish_signal = pyqtSignal(bool)
|
||||
|
||||
# heightSingal = pyqtSignal(int)
|
||||
def __init__(self):
|
||||
@ -112,3 +116,4 @@ class ShowContactThread(QThread):
|
||||
contact.set_avatar(contact.smallHeadImgBLOG)
|
||||
self.showSingal.emit(contact)
|
||||
# pprint(contact.__dict__)
|
||||
self.load_finish_signal.emit(True)
|
||||
|
@ -7,6 +7,7 @@
|
||||
@Version : Python3.10
|
||||
@comment : 主窗口
|
||||
"""
|
||||
import json
|
||||
from random import randint
|
||||
|
||||
from PyQt5.QtCore import *
|
||||
@ -73,37 +74,65 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.resize(QSize(800, 600))
|
||||
# self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
|
||||
self.action_desc.triggered.connect(self.about)
|
||||
self.load_data()
|
||||
self.init_ui()
|
||||
self.load_num = 0
|
||||
|
||||
def load_data(self):
|
||||
with open('./app/data/info.json', 'r', encoding='utf-8') as f:
|
||||
dic = json.loads(f.read())
|
||||
wxid = dic.get('wxid')
|
||||
if wxid:
|
||||
me = MePC()
|
||||
self.set_my_info(wxid)
|
||||
|
||||
def init_ui(self):
|
||||
# self.movie = QMovie("./app/data/loading.gif")
|
||||
self.label = QLabel(self)
|
||||
self.label.setGeometry(0, 0, self.width(), self.height())
|
||||
# self.label.setMovie(self.movie)
|
||||
# self.movie.start()
|
||||
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
|
||||
tool_item = QListWidgetItem(Icon.MyInfo_Icon, '工具', self.listWidget)
|
||||
chat_item = QListWidgetItem(Icon.Chat_Icon, '聊天', self.listWidget)
|
||||
contact_item = QListWidgetItem(Icon.Contact_Icon, '好友', self.listWidget)
|
||||
myinfo_item = QListWidgetItem(Icon.MyInfo_Icon, '我的', self.listWidget)
|
||||
tool_item = QListWidgetItem(Icon.MyInfo_Icon, '工具', self.listWidget)
|
||||
|
||||
tool_window = ToolWindow()
|
||||
tool_window.get_info_signal.connect(self.set_my_info)
|
||||
self.chat_window = ChatWindow()
|
||||
self.stackedWidget.addWidget(self.chat_window)
|
||||
self.contact_window = ContactWindow()
|
||||
# self.contact_window = QWidget()
|
||||
self.stackedWidget.addWidget(self.contact_window)
|
||||
label = QLabel('我是页面', self)
|
||||
tool_window.load_finish_signal.connect(self.loading)
|
||||
self.stackedWidget.addWidget(tool_window)
|
||||
self.listWidget.setCurrentRow(0)
|
||||
self.stackedWidget.setCurrentIndex(0)
|
||||
chat_window = ChatWindow()
|
||||
self.stackedWidget.addWidget(chat_window)
|
||||
contact_window = ContactWindow()
|
||||
self.stackedWidget.addWidget(contact_window)
|
||||
label = QLabel('我是页面')
|
||||
label.setAlignment(Qt.AlignCenter)
|
||||
# 设置label的背景颜色(这里随机)
|
||||
# 这里加了一个margin边距(方便区分QStackedWidget和QLabel的颜色)
|
||||
label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||
randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||
self.stackedWidget.addWidget(label)
|
||||
self.stackedWidget.addWidget(tool_window)
|
||||
self.listWidget.setCurrentRow(3)
|
||||
self.stackedWidget.setCurrentIndex(3)
|
||||
tool_window.load_finish_signal.connect(self.loading)
|
||||
contact_window.load_finish_signal.connect(self.loading)
|
||||
chat_window.load_finish_signal.connect(self.loading)
|
||||
# self.load_window_thread = LoadWindowThread(self.stackedWidget)
|
||||
# self.load_window_thread.okSignal.connect(self.stop_loading)
|
||||
# self.load_window_thread.start()
|
||||
|
||||
def setCurrentIndex(self, row):
|
||||
if row == 1:
|
||||
self.contact_window.show_contacts()
|
||||
self.stackedWidget.setCurrentIndex(row)
|
||||
if row == 2:
|
||||
self.stackedWidget.currentWidget().show_contacts()
|
||||
|
||||
def setWindow(self, window):
|
||||
try:
|
||||
window.load_finish_signal.connect(self.loading)
|
||||
except:
|
||||
pass
|
||||
self.stackedWidget.addWidget(window)
|
||||
|
||||
def set_my_info(self, wxid):
|
||||
self.avatar = QPixmap()
|
||||
@ -115,9 +144,24 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.avatar.scaled(60, 60)
|
||||
me = MePC()
|
||||
me.set_avatar(img_bytes)
|
||||
dic = {
|
||||
'wxid': wxid
|
||||
}
|
||||
with open('./app/data/info.json', 'w', encoding='utf-8') as f:
|
||||
f.write(json.dumps(dic))
|
||||
self.myavatar.setScaledContents(True)
|
||||
self.myavatar.setPixmap(self.avatar)
|
||||
|
||||
def stop_loading(self, a0):
|
||||
self.label.setVisible(False)
|
||||
|
||||
def loading(self, a0):
|
||||
self.load_num += 1
|
||||
# print('加载一个了')
|
||||
if self.load_num == 2:
|
||||
# print('ok了')
|
||||
self.label.setVisible(False)
|
||||
|
||||
def about(self):
|
||||
"""
|
||||
关于
|
||||
@ -125,7 +169,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
QMessageBox.about(self, "关于",
|
||||
f"版本:{config.version}\n"
|
||||
f"QQ交流群:{config.contact}\n"
|
||||
"地址:https://github.com/LC044/WeChatMsg"
|
||||
"地址:https://github.com/LC044/WeChatMsg\n"
|
||||
f"新特性:\n{''.join(['*' + i for i in config.description])}"
|
||||
)
|
||||
|
||||
def close(self) -> bool:
|
||||
@ -133,3 +178,26 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
del self.stackedWidget
|
||||
msg.close()
|
||||
self.contact_window.close()
|
||||
|
||||
|
||||
class LoadWindowThread(QThread):
|
||||
windowSignal = pyqtSignal(QWidget)
|
||||
okSignal = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, stackedWidget):
|
||||
super().__init__()
|
||||
self.stackedWidget = stackedWidget
|
||||
|
||||
def run(self):
|
||||
chat_window = ChatWindow()
|
||||
self.stackedWidget.addWidget(chat_window)
|
||||
contact_window = ContactWindow()
|
||||
self.stackedWidget.addWidget(contact_window)
|
||||
label = QLabel('我是页面')
|
||||
label.setAlignment(Qt.AlignCenter)
|
||||
# 设置label的背景颜色(这里随机)
|
||||
# 这里加了一个margin边距(方便区分QStackedWidget和QLabel的颜色)
|
||||
label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||
randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||
self.stackedWidget.addWidget(label)
|
||||
self.okSignal.emit(True)
|
||||
|
@ -46,12 +46,14 @@ HistoryPanel::item:hover {
|
||||
|
||||
class ToolWindow(QWidget, Ui_Dialog):
|
||||
get_info_signal = pyqtSignal(str)
|
||||
load_finish_signal = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.setStyleSheet(Stylesheet)
|
||||
self.init_ui()
|
||||
self.load_finish_signal.emit(True)
|
||||
|
||||
def init_ui(self):
|
||||
self.listWidget.clear()
|
||||
|
BIN
doc/images/chat_.png
Normal file
BIN
doc/images/chat_.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
@ -40,6 +40,8 @@
|
||||
|
||||
<details>
|
||||
|
||||
<img alt="聊天界面" src="doc/images/chat_.png"/>
|
||||
|
||||
<img alt="image-20230520235113261" src="doc/images/image-20230520235113261.png"/>
|
||||
|
||||

|
||||
@ -97,6 +99,9 @@ pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
* [数据库功能介绍](./doc/数据库介绍.md)
|
||||
* [更多功能介绍](./doc/电脑端使用教程.md)
|
||||
|
||||
显示效果
|
||||
<img alt="聊天界面" src="doc/images/chat_.png"/>
|
||||
|
||||
</details>
|
||||
|
||||
### 使用模拟器
|
||||
|
Loading…
Reference in New Issue
Block a user