diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 066ce8f..4c87ef5 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,11 +4,13 @@
-
+
-
-
+
+
+
+
@@ -80,7 +82,7 @@
-
+
@@ -88,15 +90,15 @@
- {
- "keyToString": {
- "DefaultHtmlFileTemplate": "HTML File",
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "last_opened_file_path": "D:/Program Files/Python310/Scripts/pyuic5.exe",
- "settings.editor.selected.configurable": "preferences.pluginManager"
+
+}]]>
@@ -104,8 +106,50 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -117,7 +161,7 @@
-
+
@@ -126,7 +170,7 @@
-
+
@@ -134,35 +178,14 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -210,7 +233,7 @@
-
+
@@ -218,14 +241,14 @@
-
+
-
+
-
+
@@ -233,11 +256,11 @@
-
+
+
+
+
-
-
-
@@ -253,34 +276,6 @@
1672848140146
-
- 1680670947385
-
-
-
- 1680670947385
-
-
- 1682305451381
-
-
-
- 1682305451381
-
-
- 1684598124207
-
-
-
- 1684598124207
-
-
- 1684598177829
-
-
-
- 1684598177830
-
1684598440645
@@ -596,7 +591,35 @@
1700145601841
-
+
+ 1700147800698
+
+
+
+ 1700147800698
+
+
+ 1700150198343
+
+
+
+ 1700150198343
+
+
+ 1700228064961
+
+
+
+ 1700228064961
+
+
+ 1700232296923
+
+
+
+ 1700232296923
+
+
@@ -632,9 +655,6 @@
-
-
-
@@ -646,7 +666,6 @@
-
@@ -657,7 +676,11 @@
-
+
+
+
+
+
@@ -679,6 +702,21 @@
103
+
+ file://$PROJECT_DIR$/app/person.py
+ 101
+
+
+
+ file://$PROJECT_DIR$/app/person.py
+ 99
+
+
+
+ file://$PROJECT_DIR$/app/person.py
+ 100
+
+
diff --git a/app/DataBase/micro_msg.py b/app/DataBase/micro_msg.py
index 2abfa61..5c0b78d 100644
--- a/app/DataBase/micro_msg.py
+++ b/app/DataBase/micro_msg.py
@@ -1,5 +1,6 @@
import os.path
import sqlite3
+import time
DB = None
cursor = None
@@ -25,15 +26,25 @@ def is_database_exist():
def get_contact():
- 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
- '''
- cursor.execute(sql)
- result = cursor.fetchall()
- # pprint(result)
- # print(len(result))
+ try:
+ 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
+ order by PYInitial
+ '''
+ cursor.execute(sql)
+ result = cursor.fetchall()
+ # DB.commit()
return result
diff --git a/app/DataBase/misc.py b/app/DataBase/misc.py
index 357d6ce..c5d885f 100644
--- a/app/DataBase/misc.py
+++ b/app/DataBase/misc.py
@@ -1,6 +1,8 @@
import os.path
import sqlite3
+import threading
+lock = threading.Lock()
DB = None
cursor = None
misc_path = "./app/Database/Msg/Misc.db"
@@ -17,11 +19,15 @@ def get_avatar_buffer(userName):
from ContactHeadImg1
where usrName=?;
'''
- cursor.execute(sql, [userName])
- result = cursor.fetchall()
- # print(result[0][0])
- if result:
- return result[0][0]
+ try:
+ lock.acquire(True)
+ cursor.execute(sql, [userName])
+ result = cursor.fetchall()
+ # print(result[0][0])
+ if result:
+ return result[0][0]
+ finally:
+ lock.release()
return None
diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py
index 6aa9b6b..4b4a94e 100644
--- a/app/DataBase/msg.py
+++ b/app/DataBase/msg.py
@@ -1,10 +1,12 @@
import os.path
import re
import sqlite3
+import threading
DB = []
cursor = []
msg_root_path = "./app/Database/Msg/"
+lock = threading.Lock()
# misc_path = './Msg/Misc.db'
if os.path.exists(msg_root_path):
for root, dirs, files in os.walk(msg_root_path):
@@ -54,18 +56,41 @@ def get_messages(username_):
return result
+def get_message_by_num(username_, n):
+ 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
+ '''
+ result = []
+ try:
+ lock.acquire(True)
+ for cur in cursor:
+ cur = cursor[-1]
+ cur.execute(sql, [username_])
+ result_ = cur.fetchall()
+ result += result_
+ return result_
+ finally:
+ lock.release()
+ result.sort(key=lambda x: x[5])
+ return result
+
+
def close():
for db in DB:
db.close()
if __name__ == '__main__':
- from pprint import pprint
-
msg_root_path = './Msg/'
init_database()
- username = 'wxid_0o18ef858vnu22'
- result = get_messages(username)
- pprint(result)
- pprint(len(result))
+ # username = 'wxid_0o18ef858vnu22'
+ # result = get_messages(username)
+ # pprint(result)
+ # pprint(len(result))
+ result = get_message_by_num('wxid_0o18ef858vnu22', 0)
+ print(result)
diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py
index fe3b46b..8b44654 100644
--- a/app/components/bubble_message.py
+++ b/app/components/bubble_message.py
@@ -1,87 +1,319 @@
-from Lib import QtNinePatch2
-
-from PyQt5.QtCore import Qt, QRectF
-from PyQt5.QtGui import QImage, QPainter, QColor, QFont, QPixmap
-from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy
+from PIL import Image
+from PyQt5 import QtGui
+from PyQt5.QtCore import QSize, pyqtSignal, Qt, QThread
+from PyQt5.QtGui import QPainter, QFont, QColor, QPixmap, QPolygon
+from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QSizePolicy, QVBoxLayout, QSpacerItem, \
+ QScrollArea, QScrollBar
-class Label(QLabel):
+class TextMessage(QLabel):
+ heightSingal = pyqtSignal(int)
- def __init__(self, *args, **kwargs):
- super(Label, self).__init__()
- # .9 格式的图片
- filp = kwargs.get('filp')
- self.image = QImage('Data/skin_aio_friend_bubble_pressed.9.png')
- if filp:
- self.image = self.image.mirrored(True, False)
- self.txt = kwargs.get('text')
+ def __init__(self, text, is_send=False, parent=None):
+ super(TextMessage, self).__init__(text, parent)
+ self.setFont(QFont('微软雅黑', 12))
+ self.setWordWrap(True)
+ # self.adjustSize()
+ self.setMaximumWidth(800)
+ self.setMinimumWidth(100)
+ self.setMinimumHeight(45)
+ # self.resize(QSize(100,40))
+
+ self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
- self.adjustSize()
+ # 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;
+ '''
+ )
+ w = len(text) * 16 + 30
+ if w < self.width():
+ self.setMaximumWidth(w)
- def showEvent(self, event):
- super(Label, self).showEvent(event)
- pixmap = QtNinePatch2.createPixmapFromNinePatchImage(
- self.image, self.width(), self.height())
- self.setPixmap(pixmap)
+ def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
+ super(TextMessage, self).paintEvent(a0)
- #
- def paintEvent(self, event) -> None:
- super(Label, self).paintEvent(event)
- painter = QPainter(self)
- painter.begin(self)
- painter.setPen(QColor(150, 100, 23))
- painter.setFont(QFont('SimSun', 20))
- painter.setRenderHint(QPainter.Antialiasing)
- painter.setRenderHint(QPainter.SmoothPixmapTransform)
- rec = QRectF(30, 40, self.width() - 60, self.height() - 60)
- painter.drawText(rec, Qt.TextWordWrap, self.txt)
- painter.end()
- #
- def resizeEvent(self, event):
- super(Label, self).resizeEvent(event)
- pixmap = QtNinePatch2.createPixmapFromNinePatchImage(
- self.image, self.width(), self.height())
- self.setPixmap(pixmap)
+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 == 1:
+ 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)
+
+
+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)
+
+
+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))
+
+
+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()
+
+
+class ImageMessage(QLabel):
+ def __init__(self, avatar, parent=None):
+ super().__init__(parent)
+ 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)
+ self.setScaledContents(True)
+
+ def mousePressEvent(self, event):
+ if event.buttons() == Qt.LeftButton: # 左键按下
+ self.open_image_thread = OpenImageThread(self.image_path)
+ self.open_image_thread.start()
class BubbleMessage(QWidget):
- def __init__(self, text, avatar, isSend=False, parent=None):
+ def __init__(self, str_content, avatar, Type, is_send=False, parent=None):
super().__init__(parent)
- self.isSend = isSend
-
- self.txt = text
+ self.isSend = is_send
+ # self.set
+ self.setStyleSheet(
+ '''
+ border:none;
+ '''
+ )
layout = QHBoxLayout()
- self.avatar = QLabel()
- self.avatar.setPixmap(avatar)
- self.message = Label(text=text, filp=isSend)
- if isSend:
- layout.addWidget(self.message)
- layout.addWidget(self.avatar, 0, Qt.AlignTop)
- layout.setStretch(0, 1)
+ layout.setSpacing(0)
+ layout.setContentsMargins(0, 5, 5, 5)
+ self.avatar = Avatar(avatar)
+ triangle = Triangle(Type, is_send)
+ if Type == 1:
+ self.message = TextMessage(str_content, is_send)
+ # self.message.setMaximumWidth(int(self.width() * 0.6))
else:
- layout.addWidget(self.avatar, 0, Qt.AlignTop)
- layout.addWidget(self.message)
- layout.setStretch(1, 1)
+ 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;
+ '''
+ self.spacerItem = QSpacerItem(45 + 6, 45, QSizePolicy.Expanding, QSizePolicy.Minimum)
+ if is_send:
+ layout.addItem(self.spacerItem)
+ 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)
+ layout.addWidget(self.message, 1)
+ layout.addItem(self.spacerItem)
self.setLayout(layout)
- def resizeEvent(self, a0) -> None:
- w = (self.message.width() - 60) // 27
- row = int(len(self.txt) // w) + 1
- print('row', row)
- self.message.setMaximumHeight(row * 31 + 80)
- return
+
+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())
-class MainWindow(QWidget):
+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);
+ }
+ '''
+ )
+
+
+class MyWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.resize(500, 200)
txt = '''在工具中单击边缘可以添加黑点,单击可以删掉黑点,拖动可以调整黑点长度。勾选等选项可以查看内容、缩放等区域右侧可预览不同拉伸情况下的效果,拖动可以调整预览的拉伸比例'''
- avatar = QPixmap('Data/head.jpg').scaled(60, 60)
- bubble_mesage = BubbleMessage(txt, avatar, isSend=False)
+ avatar = '../data/icons/default_avatar.svg'
+ bubble_message = BubbleMessage(txt, avatar, Type=1, is_send=False)
layout = QVBoxLayout()
- bubble_mesage1 = BubbleMessage(txt, avatar, isSend=True)
- layout.addWidget(bubble_mesage)
- layout.addWidget(bubble_mesage1)
+ 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)
+ 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.setLayout(layout)
+
+
+class Test(QWidget):
+ def __init__(self):
+ super().__init__()
+ layout = QVBoxLayout()
+ self.resize(500, 600)
+ w1 = MyWidget()
+ w2 = QLabel("nihao")
+ layout.addWidget(w1)
+ layout.addWidget(w2)
+ self.setLayout(layout)
+
+
+if __name__ == '__main__':
+ app = QApplication([])
+ widget = Test()
+ # widget = MyWidget()
+ widget.show()
+ app.exec_()
diff --git a/app/config.py b/app/config.py
index 87ce4e1..37ed164 100644
--- a/app/config.py
+++ b/app/config.py
@@ -1,2 +1,2 @@
-version = '0.2.0'
+version = '0.2.1'
contact = '474379264'
diff --git a/app/person.py b/app/person.py
index 09f22a4..0ad5ad5 100644
--- a/app/person.py
+++ b/app/person.py
@@ -13,6 +13,7 @@ from app.Ui.Icon import Icon
class Person:
def __init__(self, wxid: str):
+
self.wxid = wxid
self.conRemark = data.get_conRemark(wxid)
self.nickname, self.alias = data.get_nickname(wxid)
@@ -39,6 +40,33 @@ class Contact(Person):
self.bigHeadImgUrl = ''
+def singleton(cls):
+ _instance = {}
+
+ def inner():
+ if cls not in _instance:
+ _instance[cls] = cls()
+ return _instance[cls]
+
+ return inner
+
+
+@singleton
+class MePC:
+ def __init__(self):
+ self.avatar = QPixmap(Icon.Default_avatar_path)
+
+ def set_avatar(self, img_bytes):
+ if not img_bytes:
+ self.avatar.load(Icon.Default_avatar_path)
+ return
+ if img_bytes[:4] == b'\x89PNG':
+ self.avatar.loadFromData(img_bytes, format='PNG')
+ else:
+ self.avatar.loadFromData(img_bytes, format='jfif')
+ self.avatar = QPixmap()
+
+
class ContactPC:
def __init__(self, contact_info: Dict):
self.wxid = contact_info.get('UserName')
@@ -46,6 +74,8 @@ class ContactPC:
# Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl,bigHeadImgUrl
self.alias = contact_info.get('Alias')
self.nickName = contact_info.get('NickName')
+ if not self.remark:
+ self.remark = self.nickName
self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl')
self.smallHeadImgBLOG = b''
self.avatar = QPixmap()
@@ -64,3 +94,9 @@ class ContactPC:
class Group(Person):
def __init__(self, wxid: str):
super(Group, self).__init__(wxid)
+
+
+if __name__ == '__main__':
+ p1 = MePC()
+ p2 = MePC()
+ print(p1 == p2)
diff --git a/app/ui_pc/chat/__init__.py b/app/ui_pc/chat/__init__.py
new file mode 100644
index 0000000..00e557b
--- /dev/null
+++ b/app/ui_pc/chat/__init__.py
@@ -0,0 +1 @@
+from .chat_window import ChatWindow
diff --git a/app/ui_pc/chat/chatInfoUi.py b/app/ui_pc/chat/chatInfoUi.py
new file mode 100644
index 0000000..62c03c5
--- /dev/null
+++ b/app/ui_pc/chat/chatInfoUi.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'chatInfoUi.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, QtWidgets
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ self.verticalLayout = QtWidgets.QVBoxLayout(Form)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setSpacing(0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.frame = QtWidgets.QFrame(Form)
+ self.frame.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.label_reamrk = QtWidgets.QLabel(self.frame)
+ self.label_reamrk.setObjectName("label_reamrk")
+ self.horizontalLayout_2.addWidget(self.label_reamrk)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_2.addItem(spacerItem)
+ self.toolButton = QtWidgets.QToolButton(self.frame)
+ self.toolButton.setObjectName("toolButton")
+ self.horizontalLayout_2.addWidget(self.toolButton)
+ self.verticalLayout_2.addLayout(self.horizontalLayout_2)
+
+ self.verticalLayout.addWidget(self.frame)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.label_reamrk.setText(_translate("Form", "TextLabel"))
+ self.toolButton.setText(_translate("Form", "..."))
diff --git a/app/ui_pc/chat/chatInfoUi.ui b/app/ui_pc/chat/chatInfoUi.ui
new file mode 100644
index 0000000..bb8c9aa
--- /dev/null
+++ b/app/ui_pc/chat/chatInfoUi.ui
@@ -0,0 +1,96 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 817
+ 748
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
-
+
+
-
+
+
+ TextLabel
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ ...
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 797
+ 700
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/ui_pc/chat/chatUi.py b/app/ui_pc/chat/chatUi.py
new file mode 100644
index 0000000..b617835
--- /dev/null
+++ b/app/ui_pc/chat/chatUi.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'chatUi.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, QtWidgets
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.resize(840, 752)
+ Form.setStyleSheet("background: rgb(240, 240, 240);")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Form)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_2.setSpacing(0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.label = QtWidgets.QLabel(Form)
+ self.label.setText("")
+ self.label.setObjectName("label")
+ self.horizontalLayout.addWidget(self.label)
+ self.lineEdit = QtWidgets.QLineEdit(Form)
+ self.lineEdit.setMinimumSize(QtCore.QSize(200, 30))
+ self.lineEdit.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.lineEdit.setStyleSheet("background:transparent;\n"
+ " border-width:0;\n"
+ " border-style:outset;\n"
+ " background-color:rgb(226,226,226);\n"
+ " ")
+ self.lineEdit.setCursorMoveStyle(QtCore.Qt.VisualMoveStyle)
+ self.lineEdit.setObjectName("lineEdit")
+ self.horizontalLayout.addWidget(self.lineEdit)
+ self.label_2 = QtWidgets.QLabel(Form)
+ self.label_2.setText("")
+ self.label_2.setObjectName("label_2")
+ self.horizontalLayout.addWidget(self.label_2)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+ self.verticalLayout_2.addLayout(self.verticalLayout)
+ self.listWidget = QtWidgets.QListWidget(Form)
+ self.listWidget.setMinimumSize(QtCore.QSize(250, 0))
+ self.listWidget.setMaximumSize(QtCore.QSize(250, 16777215))
+ self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+ self.listWidget.setObjectName("listWidget")
+ self.verticalLayout_2.addWidget(self.listWidget)
+ self.verticalLayout_2.setStretch(1, 1)
+ self.horizontalLayout_2.addLayout(self.verticalLayout_2)
+ self.stackedWidget = QtWidgets.QStackedWidget(Form)
+ self.stackedWidget.setObjectName("stackedWidget")
+ self.horizontalLayout_2.addWidget(self.stackedWidget)
+ self.horizontalLayout_2.setStretch(1, 1)
+
+ self.retranslateUi(Form)
+ self.stackedWidget.setCurrentIndex(-1)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
diff --git a/app/ui_pc/chat/chatUi.ui b/app/ui_pc/chat/chatUi.ui
new file mode 100644
index 0000000..116c90c
--- /dev/null
+++ b/app/ui_pc/chat/chatUi.ui
@@ -0,0 +1,105 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 840
+ 752
+
+
+
+ Form
+
+
+ background: rgb(240, 240, 240);
+
+
+ -
+
+
+ 0
+
+
-
+
+
-
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+ 200
+ 30
+
+
+
+
+ 200
+ 16777215
+
+
+
+ background:transparent;
+ border-width:0;
+ border-style:outset;
+ background-color:rgb(226,226,226);
+
+
+
+ Qt::VisualMoveStyle
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 250
+ 0
+
+
+
+
+ 250
+ 16777215
+
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+
+
+
+ -
+
+
+ -1
+
+
+
+
+
+
+
+
diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py
new file mode 100644
index 0000000..72f0573
--- /dev/null
+++ b/app/ui_pc/chat/chat_info.py
@@ -0,0 +1,85 @@
+from PyQt5.QtCore import QThread, pyqtSignal, Qt
+from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSpacerItem, QSizePolicy, QLabel, QHBoxLayout
+
+from app.DataBase import msg
+from app.components.bubble_message import BubbleMessage, ScrollBar, ScrollArea, ScrollAreaContent
+from app.person import MePC
+
+
+class ChatInfo(QWidget):
+ def __init__(self, contact, parent=None):
+ super().__init__(parent)
+ self.contact = contact
+
+ self.init_ui()
+ self.show_chats()
+
+ def init_ui(self):
+ self.label_reamrk = QLabel(self.contact.remark)
+
+ self.hBoxLayout = QHBoxLayout()
+ self.hBoxLayout.addWidget(self.label_reamrk)
+
+ self.vBoxLayout = QVBoxLayout()
+ self.vBoxLayout.setSpacing(0)
+ # 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)
+
+ def show_chats(self):
+ self.show_chat_thread = ShowChatThread(self.contact)
+ self.show_chat_thread.showSingal.connect(self.show_chat)
+ 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)
+
+ def show_chat(self, message):
+ try:
+ type_ = message[2]
+ # print(type_, type(type_))
+ is_send = message[4]
+ avatar = MePC().avatar if is_send else self.contact.avatar
+ if type_ == 1:
+ str_content = message[7]
+ bubble_message = BubbleMessage(
+ str_content,
+ avatar,
+ type_,
+ is_send
+ )
+ # print(str_content)
+ self.scroolAreaLayout.addWidget(bubble_message)
+ except:
+ print(message)
+
+
+class ShowChatThread(QThread):
+ showSingal = pyqtSignal(tuple)
+ finishSingal = pyqtSignal(int)
+
+ # heightSingal = pyqtSignal(int)
+ def __init__(self, contact):
+ super().__init__()
+ self.wxid = contact.wxid
+
+ def run(self) -> None:
+ messages = msg.get_message_by_num(self.wxid, 0)
+ for message in messages:
+ self.showSingal.emit(message)
+ self.finishSingal.emit(1)
diff --git a/app/ui_pc/chat/chat_window.py b/app/ui_pc/chat/chat_window.py
new file mode 100644
index 0000000..c5e687f
--- /dev/null
+++ b/app/ui_pc/chat/chat_window.py
@@ -0,0 +1,115 @@
+from PyQt5.QtCore import QThread, pyqtSignal
+from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QLineEdit
+
+from app.DataBase import micro_msg, misc
+from app.components import ContactQListWidgetItem
+from app.person import ContactPC
+from .chatUi import Ui_Form
+from .chat_info import ChatInfo
+from ..Icon import Icon
+
+# 美化样式表
+Stylesheet = """
+
+/*去掉item虚线边框*/
+QListWidget, QListView, QTreeWidget, QTreeView {
+ outline: 0px;
+ border:none;
+ background-color:rgb(240,240,240)
+}
+/*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/
+QListWidget {
+ min-width: 250px;
+ max-width: 250px;
+ min-height: 80px;
+ max-height: 1200px;
+ color: black;
+ border:none;
+}
+QListWidget::item{
+ height:60px;
+ width:250px;
+}
+/*被选中时的背景颜色和左边框颜色*/
+QListWidget::item:selected {
+ background: rgb(204, 204, 204);
+ border-bottom: 2px solid rgb(9, 187, 7);
+ border-left:none;
+ color: black;
+ font-weight: bold;
+}
+/*鼠标悬停颜色*/
+HistoryPanel::item:hover {
+ background: rgb(52, 52, 52);
+}
+"""
+
+
+class ChatWindow(QWidget, Ui_Form):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.show_thread = None
+ self.setupUi(self)
+ self.ok_flag = False
+ self.setStyleSheet(Stylesheet)
+ self.init_ui()
+ self.show_chats()
+
+ def init_ui(self):
+ search_action = QAction(self.lineEdit)
+ search_action.setIcon(Icon.Search_Icon)
+ self.lineEdit.addAction(search_action, QLineEdit.LeadingPosition)
+ self.listWidget.clear()
+ self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
+ self.listWidget.setCurrentRow(0)
+ self.stackedWidget.setCurrentIndex(0)
+
+ def show_chats(self):
+ print('chat0')
+ if self.ok_flag:
+ return
+ micro_msg.init_database()
+ if not micro_msg.is_database_exist():
+ QMessageBox.critical(self, "错误", "数据库不存在\n请先解密数据库")
+ return
+ self.show_thread = ShowContactThread()
+ self.show_thread.showSingal.connect(self.show_chat)
+ self.show_thread.start()
+ self.ok_flag = True
+
+ def show_chat(self, contact):
+ contact_item = ContactQListWidgetItem(contact.nickName, 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)
+ self.stackedWidget.setCurrentIndex(row)
+
+
+class ShowContactThread(QThread):
+ showSingal = pyqtSignal(ContactPC)
+
+ # heightSingal = pyqtSignal(int)
+ def __init__(self):
+ super().__init__()
+
+ def run(self) -> None:
+ contact_info_lists = micro_msg.get_contact()
+ for contact_info_list in contact_info_lists:
+ # UserName, Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl,bigHeadImgUrl
+ contact_info = {
+ 'UserName': contact_info_list[0],
+ 'Alias': contact_info_list[1],
+ 'Type': contact_info_list[2],
+ 'Remark': contact_info_list[3],
+ 'NickName': contact_info_list[4],
+ 'smallHeadImgUrl': contact_info_list[7]
+ }
+ contact = ContactPC(contact_info)
+ contact.smallHeadImgBLOG = misc.get_avatar_buffer(contact.wxid)
+ contact.set_avatar(contact.smallHeadImgBLOG)
+ self.showSingal.emit(contact)
+ # pprint(contact.__dict__)
diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py
index 0b051e7..8d7165b 100644
--- a/app/ui_pc/mainview.py
+++ b/app/ui_pc/mainview.py
@@ -10,14 +10,17 @@
from random import randint
from PyQt5.QtCore import *
+from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *
from app import config
-from app.DataBase import msg
+from app.DataBase import msg, misc
from app.Ui.Icon import Icon
from . import mainwindow
+from .chat import ChatWindow
from .contact import ContactWindow
from .tool import ToolWindow
+from ..person import MePC
# 美化样式表
Stylesheet = """
@@ -67,6 +70,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
self.setWindowIcon(Icon.MainWindow_Icon)
self.setStyleSheet(Stylesheet)
self.listWidget.clear()
+ self.resize(QSize(800, 600))
# self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
self.action_desc.triggered.connect(self.about)
self.init_ui()
@@ -79,14 +83,11 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
tool_item = QListWidgetItem(Icon.MyInfo_Icon, '工具', self.listWidget)
tool_window = ToolWindow()
- label = QLabel('我是页面', self)
- 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)
+ 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)
label.setAlignment(Qt.AlignCenter)
@@ -104,6 +105,19 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
self.contact_window.show_contacts()
self.stackedWidget.setCurrentIndex(row)
+ def set_my_info(self, wxid):
+ self.avatar = QPixmap()
+ img_bytes = misc.get_avatar_buffer(wxid)
+ if img_bytes[:4] == b'\x89PNG':
+ self.avatar.loadFromData(img_bytes, format='PNG')
+ else:
+ self.avatar.loadFromData(img_bytes, format='jfif')
+ self.avatar.scaled(60, 60)
+ me = MePC()
+ me.set_avatar(img_bytes)
+ self.myavatar.setScaledContents(True)
+ self.myavatar.setPixmap(self.avatar)
+
def about(self):
"""
关于
diff --git a/app/ui_pc/tool/pc_decrypt/decryptUi.py b/app/ui_pc/tool/pc_decrypt/decryptUi.py
index 44145d5..99579ae 100644
--- a/app/ui_pc/tool/pc_decrypt/decryptUi.py
+++ b/app/ui_pc/tool/pc_decrypt/decryptUi.py
@@ -51,7 +51,9 @@ class Ui_Dialog(object):
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(Dialog)
- self.lineEdit.setStyleSheet("background:transparent;border-width:0;border-style:outset")
+ self.lineEdit.setStyleSheet("\n"
+ " background:transparent;border-width:0;border-style:outset\n"
+ " ")
self.lineEdit.setFrame(False)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1)
@@ -62,6 +64,7 @@ class Ui_Dialog(object):
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1)
self.label_key = QtWidgets.QLabel(Dialog)
+ self.label_key.setMaximumSize(QtCore.QSize(200, 16777215))
self.label_key.setText("")
self.label_key.setObjectName("label_key")
self.gridLayout.addWidget(self.label_key, 5, 1, 1, 1)
@@ -90,6 +93,7 @@ class Ui_Dialog(object):
self.label_8.setObjectName("label_8")
self.gridLayout.addWidget(self.label_8, 6, 0, 1, 1)
self.label_db_dir = QtWidgets.QLabel(Dialog)
+ self.label_db_dir.setMaximumSize(QtCore.QSize(200, 300))
self.label_db_dir.setText("")
self.label_db_dir.setObjectName("label_db_dir")
self.gridLayout.addWidget(self.label_db_dir, 6, 1, 1, 1)
diff --git a/app/ui_pc/tool/pc_decrypt/decryptUi.ui b/app/ui_pc/tool/pc_decrypt/decryptUi.ui
index 846fc4c..04d9673 100644
--- a/app/ui_pc/tool/pc_decrypt/decryptUi.ui
+++ b/app/ui_pc/tool/pc_decrypt/decryptUi.ui
@@ -117,6 +117,12 @@
-
+
+
+ 200
+ 16777215
+
+
@@ -173,6 +179,12 @@
-
+
+
+ 200
+ 300
+
+
diff --git a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py
index af71116..41f19f7 100644
--- a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py
+++ b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py
@@ -12,7 +12,7 @@ from . import decryptUi
class DecryptControl(QWidget, decryptUi.Ui_Dialog):
DecryptSignal = pyqtSignal(str)
- registerSignal = pyqtSignal(str)
+ get_wxidSignal = pyqtSignal(str)
def __init__(self, parent=None):
super(DecryptControl, self).__init__(parent)
@@ -46,6 +46,8 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
self.label_pid.setText(str(self.info['pid']))
self.label_version.setText(self.info['version'])
self.lineEdit.setFocus()
+ self.checkBox.setChecked(True)
+ self.get_wxidSignal.emit(self.info['wxid'])
if self.wx_dir and os.path.exists(os.path.join(self.wx_dir, self.info['wxid'])):
self.label_ready.setText('已就绪')
except Exception as e:
@@ -59,6 +61,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
if directory:
self.label_db_dir.setText(directory)
self.wx_dir = directory
+ self.checkBox_2.setChecked(True)
if self.ready:
self.label_ready.setText('已就绪')
diff --git a/app/ui_pc/tool/tool_window.py b/app/ui_pc/tool/tool_window.py
index 29d1bf3..0963e2d 100644
--- a/app/ui_pc/tool/tool_window.py
+++ b/app/ui_pc/tool/tool_window.py
@@ -1,6 +1,6 @@
from random import randint
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel
from .pc_decrypt import DecryptControl
@@ -45,6 +45,8 @@ HistoryPanel::item:hover {
class ToolWindow(QWidget, Ui_Dialog):
+ get_info_signal = pyqtSignal(str)
+
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
@@ -58,8 +60,9 @@ class ToolWindow(QWidget, Ui_Dialog):
contact_item = QListWidgetItem(Icon.Contact_Icon, 'None', self.listWidget)
myinfo_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget)
tool_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget)
- tool_window = DecryptControl()
- self.stackedWidget.addWidget(tool_window)
+ decrypt_window = DecryptControl()
+ decrypt_window.get_wxidSignal.connect(self.get_info_signal)
+ self.stackedWidget.addWidget(decrypt_window)
label = QLabel('我是页面', self)
label.setAlignment(Qt.AlignCenter)
# 设置label的背景颜色(这里随机)
diff --git a/decrypt_window.py b/decrypt_window.py
index 04f7b7b..4151aa7 100644
--- a/decrypt_window.py
+++ b/decrypt_window.py
@@ -1,11 +1,9 @@
import ctypes
import sys
-import time
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
-from app.ui_pc import mainview
from app.ui_pc.tool.pc_decrypt import pc_decrypt
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport")
@@ -28,23 +26,6 @@ class ViewController(QWidget):
self.viewDecrypt.DecryptSignal.connect(self.show_success)
self.viewDecrypt.show()
- def loadMainWinView(self, username=None):
- """
- 聊天界面
- :param username: 账号
- :return:
- """
- username = ''
- start = time.time()
- self.viewMainWIn = mainview.MainWinController(username=username)
- self.viewMainWIn.setWindowTitle("Chat")
- # print(username)
- self.viewMainWIn.username = username
- # self.viewMainWIn.exitSignal.connect(self.loadDecryptView) # 不需要回到登录界面可以省略
- self.viewMainWIn.show()
- end = time.time()
- print('ok', end - start)
-
def show_success(self):
QMessageBox.about(self, "解密成功", "数据库文件存储在\napp/DataBase/Msg\n文件夹下")
@@ -52,7 +33,5 @@ class ViewController(QWidget):
if __name__ == '__main__':
app = QApplication(sys.argv)
view = ViewController()
- # view.loadPCDecryptView()
- view.loadMainWinView()
- # view.show_success()
+ view.loadPCDecryptView()
sys.exit(app.exec_())
diff --git a/doc/images/messages_demo.png b/doc/images/messages_demo.png
new file mode 100644
index 0000000..75da423
Binary files /dev/null and b/doc/images/messages_demo.png differ
diff --git a/doc/images/pc_contact.png b/doc/images/pc_contact.png
new file mode 100644
index 0000000..5770fd8
Binary files /dev/null and b/doc/images/pc_contact.png differ
diff --git a/doc/数据库介绍.md b/doc/数据库介绍.md
index 48510a2..2e3dd95 100644
--- a/doc/数据库介绍.md
+++ b/doc/数据库介绍.md
@@ -1,3 +1,4 @@
# 微信数据库介绍
-**这个人比较懒,还什么都没写**
\ No newline at end of file
+**这个人比较懒,还什么都没写**
+
diff --git a/doc/电脑端使用教程.md b/doc/电脑端使用教程.md
new file mode 100644
index 0000000..b7aaf05
--- /dev/null
+++ b/doc/电脑端使用教程.md
@@ -0,0 +1,71 @@
+# 一、解密微信数据库
+
+## 主要功能
+
+1. 解密微信数据库
+2. 查看聊天记录
+3. 导出聊天记录
+ * CSV
+ * docx(待实现)
+ * HTML(待实现)
+
+## 安装
+
+```shell
+git clone https://github.com/LC044/WeChatMsg
+cd WeChatMsg
+pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
+```
+
+## 解密
+
+
+
+解密步骤:
+
+1. 登录微信
+
+2. 运行程序
+
+ ```shell
+ python decrypt_window.py
+ ```
+
+3. 点击获取信息
+
+ 
+
+4. 设置微信安装路径
+ 可以到微信->设置->文件管理查看
+
+ 
+
+ 点击**设置微信路径**按钮,选择该文件夹路径
+
+5. 获取到密钥和微信路径之后点击开始解密
+
+6. 解密后的数据库文件保存在./app/DataBase/Msg路径下
+
+
+
+## 查看聊天记录
+
+
+
+1. 运行程序
+
+```shell
+python main_pc.py
+```
+
+2. 选择联系人
+
+
+
+3. 导出聊天记录
+
+聊天记录保存在 **/data/聊天记录/** 文件夹下
+
+
+
+
\ No newline at end of file
diff --git a/main_pc.py b/main_pc.py
new file mode 100644
index 0000000..04f7b7b
--- /dev/null
+++ b/main_pc.py
@@ -0,0 +1,58 @@
+import ctypes
+import sys
+import time
+
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import *
+
+from app.ui_pc import mainview
+from app.ui_pc.tool.pc_decrypt import pc_decrypt
+
+ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport")
+
+
+class ViewController(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle('解密')
+ self.setWindowIcon(QIcon('./app/data/icons/logo.svg'))
+ self.viewMainWIn = None
+ self.viewDecrypt = None
+
+ def loadPCDecryptView(self):
+ """
+ 登录界面
+ :return:
+ """
+ self.viewDecrypt = pc_decrypt.DecryptControl()
+ self.viewDecrypt.DecryptSignal.connect(self.show_success)
+ self.viewDecrypt.show()
+
+ def loadMainWinView(self, username=None):
+ """
+ 聊天界面
+ :param username: 账号
+ :return:
+ """
+ username = ''
+ start = time.time()
+ self.viewMainWIn = mainview.MainWinController(username=username)
+ self.viewMainWIn.setWindowTitle("Chat")
+ # print(username)
+ self.viewMainWIn.username = username
+ # self.viewMainWIn.exitSignal.connect(self.loadDecryptView) # 不需要回到登录界面可以省略
+ self.viewMainWIn.show()
+ end = time.time()
+ print('ok', end - start)
+
+ def show_success(self):
+ QMessageBox.about(self, "解密成功", "数据库文件存储在\napp/DataBase/Msg\n文件夹下")
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ view = ViewController()
+ # view.loadPCDecryptView()
+ view.loadMainWinView()
+ # view.show_success()
+ sys.exit(app.exec_())
diff --git a/readme.md b/readme.md
index 69b45d6..f9c3c9c 100644
--- a/readme.md
+++ b/readme.md
@@ -94,7 +94,8 @@ pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
随便下载一个SQLite数据库查看软件就能打开数据库,例如[DB Browser for SQLite](https://sqlitebrowser.org/dl/)
-[数据库功能介绍](./doc/数据库介绍.md)
+* [数据库功能介绍](./doc/数据库介绍.md)
+* [更多功能介绍](./doc/电脑端使用教程.md)