解决多次解密导致的数据重复问题

This commit is contained in:
shuaikangzhou 2023-12-13 22:12:50 +08:00
parent 4c6ec0ed3b
commit 9ca75c73e2
29 changed files with 2294 additions and 19 deletions

View File

@ -63,7 +63,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
from MSG
where StrTalker=?
group by MsgSvrID
order by CreateTime
'''
try:
@ -79,7 +78,6 @@ class Msg:
sql = '''
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,StrTalker,Reserved1,CompressContent
from MSG
group by MsgSvrID
order by CreateTime
'''
if not self.open_flag:
@ -116,7 +114,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
from MSG
where StrTalker = ? and localId < ?
group by MsgSvrID
order by CreateTime desc
limit 20
'''
@ -142,7 +139,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
from MSG
where StrTalker=? and Type=? and strftime('%Y',CreateTime,'unixepoch','localtime') = ?
group by MsgSvrID
order by CreateTime
'''
else:
@ -150,7 +146,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
from MSG
where StrTalker=? and Type=?
group by MsgSvrID
order by CreateTime
'''
try:
@ -171,7 +166,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra
from MSG
where StrTalker=? and Type=1 and LENGTH(StrContent)<? and StrContent like ?
group by MsgSvrID
order by CreateTime desc
'''
temp = []
@ -192,7 +186,6 @@ class Msg:
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID
from MSG
where localId > ? and StrTalker=? and Type=1 and IsSender=?
group by MsgSvrID
limit 1
'''
self.cursor.execute(sql, [local_id, username_, 1 - is_send])
@ -213,6 +206,7 @@ class Msg:
('', '', ['', ''], ''),
('', '', '', '')
))
print(keyword,res)
return res
def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'):
@ -223,7 +217,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
WHERE StrTalker = ? AND strftime('%Y', CreateTime, 'unixepoch', 'localtime') = ?
GROUP BY MsgSvrID
)
group by days
'''
@ -234,7 +227,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
WHERE StrTalker = ?
GROUP BY MsgSvrID
)
group by days
'''
@ -260,7 +252,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
WHERE StrTalker = ? AND strftime('%Y', CreateTime, 'unixepoch', 'localtime') = ?
GROUP BY MsgSvrID
)
group by days
'''
@ -271,7 +262,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
WHERE StrTalker = ?
GROUP BY MsgSvrID
)
group by days
'''
@ -300,7 +290,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
where StrTalker = ? and strftime('%Y',CreateTime,'unixepoch','localtime') = ?
GROUP BY MsgSvrID
)
group by hours
'''
@ -311,7 +300,6 @@ class Msg:
SELECT MsgSvrID, CreateTime
FROM MSG
where StrTalker = ?
GROUP BY MsgSvrID
)
group by hours
'''

View File

@ -9,7 +9,7 @@ from . import msg_db, micro_msg_db
from .package_msg import PackageMsg
from ..DataBase import hard_link_db
from ..DataBase import media_msg_db
from ..person_pc import MePC
from ..person import MePC
from ..util import path
import shutil

28
app/ui/Icon.py Normal file
View File

@ -0,0 +1,28 @@
from PyQt5.QtGui import QIcon
from app.resources import resource_rc
var = resource_rc.qt_resource_name
class Icon:
Default_avatar_path = ':/icons/icons/default_avatar.svg'
Default_image_path = ':/icons/icons/404.png'
MainWindow_Icon = QIcon(':/icons/icons/logo.svg')
Default_avatar = QIcon(Default_avatar_path)
Output = QIcon(':/icons/icons/output.svg')
Back = QIcon(':/icons/icons/back.svg')
ToDocx = QIcon(':/icons/icons/word.svg')
ToCSV = QIcon(':/icons/icons/csv.svg')
ToHTML = QIcon(':/icons/icons/html.svg')
ToTXT = QIcon(':/icons/icons/txt.svg')
Chat_Icon = QIcon(':/icons/icons/chat.svg')
Contact_Icon = QIcon(':/icons/icons/contact.svg')
MyInfo_Icon = QIcon(':/icons/icons/myinfo.svg')
Annual_Report_Icon = QIcon(':/icons/icons/annual_report.svg')
Analysis_Icon = QIcon(':/icons/icons/analysis.svg')
Emotion_Icon = QIcon(':/icons/icons/emotion.svg')
Search_Icon = QIcon(':/icons/icons/search.svg')
Tool_Icon = QIcon(':/icons/icons/tool.svg')
Home_Icon = QIcon(':/icons/icons/home.svg')
Help_Icon = QIcon(':/icons/icons/help.svg')

0
app/ui/__init__.py Normal file
View File

1
app/ui/chat/__init__.py Normal file
View File

@ -0,0 +1 @@
from .chat_window import ChatWindow

48
app/ui/chat/chatInfoUi.py Normal file
View File

@ -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", "..."))

74
app/ui/chat/chatUi.py Normal file
View File

@ -0,0 +1,74 @@
# -*- 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.setSpacing(6)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setSpacing(6)
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-radius:5px;\n"
"border-top: 0px solid #b2e281;\n"
"border-bottom: 0px solid #b2e281;\n"
"border-right: 0px solid #b2e281;\n"
"border-left: 0px solid #b2e281;\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.setMinimumSize(QtCore.QSize(30, 0))
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"))

160
app/ui/chat/chat_info.py Normal file
View File

@ -0,0 +1,160 @@
import traceback
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout
from app.DataBase import msg_db, hard_link_db
from app.components.bubble_message import BubbleMessage, ChatWidget, Notice
from app.person import MePC
from app.util import get_abs_path
from app.util.emoji import get_emoji
class ChatInfo(QWidget):
def __init__(self, contact, parent=None):
super().__init__(parent)
self.last_timestamp = 0
self.last_str_time = ''
self.last_pos = 0
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.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.add_message)
self.show_chat_thread.finishSingal.connect(self.show_finish)
# self.show_chat_thread.start()
def show_finish(self, ok):
self.setScrollBarPos()
self.show_chat_thread.quit()
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]
BytesExtra = message[10]
if type_ == 1:
if self.is_5_min(timestamp):
time_message = Notice(self.last_str_time)
self.last_str_time = str_time
self.chat_window.add_message_item(time_message, 0)
bubble_message = BubbleMessage(
str_content,
avatar,
type_,
is_send
)
self.chat_window.add_message_item(bubble_message, 0)
elif type_ == 3:
# return
if self.is_5_min(timestamp):
time_message = Notice(self.last_str_time)
self.last_str_time = str_time
self.chat_window.add_message_item(time_message, 0)
image_path = hard_link_db.get_image(content=str_content,bytesExtra=BytesExtra, thumb=False)
image_path = get_abs_path(image_path)
bubble_message = BubbleMessage(
image_path,
avatar,
type_,
is_send
)
self.chat_window.add_message_item(bubble_message, 0)
elif type_ == 47:
return
if self.is_5_min(timestamp):
time_message = Notice(self.last_str_time)
self.last_str_time = str_time
self.chat_window.add_message_item(time_message, 0)
image_path = get_emoji(str_content, thumb=True)
bubble_message = BubbleMessage(
image_path,
avatar,
3,
is_send
)
self.chat_window.add_message_item(bubble_message, 0)
elif type_ == 10000:
str_content = str_content.lstrip('<revokemsg>').rstrip('</revokemsg>')
message = Notice(str_content )
self.chat_window.add_message_item(message, 0)
except:
print(message)
traceback.print_exc()
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 = 9999999999
self.wxid = contact.wxid
def run(self) -> None:
messages = msg_db.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)

165
app/ui/chat/chat_window.py Normal file
View File

@ -0,0 +1,165 @@
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QLineEdit
from app.DataBase import micro_msg_db, misc_db, msg_db
from app.components import ContactQListWidgetItem
from app.person import ContactPC
from app.ui.Icon import Icon
from app.util import search
from .chatUi import Ui_Form
from .chat_info import ChatInfo
# 美化样式表
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):
load_finish_signal = pyqtSignal(bool)
def __init__(self, parent=None):
super().__init__(parent)
self.show_thread = None
self.setupUi(self)
self.ok_flag = False
self.setStyleSheet(Stylesheet)
self.contacts = [[], []]
self.init_ui()
self.show_chats()
self.visited = set()
def init_ui(self):
search_action = QAction(self.lineEdit)
search_action.setIcon(Icon.Search_Icon)
self.lineEdit.addAction(search_action, QLineEdit.LeadingPosition)
self.lineEdit.returnPressed.connect(self.search_contact)
self.listWidget.clear()
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
self.listWidget.setCurrentRow(0)
self.stackedWidget.setCurrentIndex(0)
def show_chats(self):
# return
if self.ok_flag:
return
msg_db.init_database()
micro_msg_db.init_database()
if not msg_db.open_flag:
QMessageBox.critical(self, "错误", "数据库不存在\n请先解密数据库")
self.show_thread = ShowThread()
self.show_thread.load_finish_signal.connect(self.load_finish_signal)
self.show_thread.start()
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 search_contact(self):
content = self.lineEdit.text()
if not content:
return
index = self.search_contact_index(content)
self.select_contact_by_index(index)
def search_contact_index(self, content: str) -> int:
return search.search_by_content(content, self.contacts)
def select_contact_by_index(self, index):
self.stackedWidget.setCurrentIndex(index)
self.listWidget.setCurrentRow(index)
def show_chat(self, contact):
self.contacts[0].append(contact.remark)
self.contacts[1].append(contact.nickName)
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)
self.stackedWidget.setCurrentIndex(row)
if row not in self.visited:
chat_info_window = self.stackedWidget.currentWidget()
chat_info_window.update_history_messages()
self.visited.add(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):
super().__init__()
def run(self) -> None:
contact_info_lists = micro_msg_db.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_db.get_avatar_buffer(contact.wxid)
contact.set_avatar(contact.smallHeadImgBLOG)
self.showSingal.emit(contact)
# pprint(contact.__dict__)
self.load_finish_signal.emit(True)
class ShowThread(QThread):
showSingal = pyqtSignal(ContactPC)
load_finish_signal = pyqtSignal(bool)
# heightSingal = pyqtSignal(int)
def __init__(self):
super().__init__()
def run(self) -> None:
QThread.sleep(1)
self.load_finish_signal.emit(True)

View File

@ -0,0 +1 @@
from .contact_window import ContactWindow

View File

@ -0,0 +1,162 @@
from PyQt5.QtCore import pyqtSignal, QUrl, QThread
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox, QDialog
from app.DataBase.output_pc import Output
from app.ui.Icon import Icon
from .contactInfoUi import Ui_Form
from .userinfo import userinfo
from ...person import ContactPC
from .export_dialog import ExportDialog
class ContactInfo(QWidget, Ui_Form):
exitSignal = pyqtSignal()
urlSignal = pyqtSignal(QUrl)
# username = ''
def __init__(self, contact, parent=None):
super(ContactInfo, self).__init__(parent)
self.setupUi(self)
self.contact: ContactPC = contact
self.view_userinfo = userinfo.UserinfoController(self.contact)
self.btn_back.clicked.connect(self.back)
self.init_ui()
def init_ui(self):
self.btn_back.setIcon(Icon.Back)
self.btn_report.setIcon(Icon.Annual_Report_Icon)
self.btn_analysis.setIcon(Icon.Analysis_Icon)
self.btn_emotion.setIcon(Icon.Emotion_Icon)
self.btn_report.clicked.connect(self.annual_report)
self.btn_analysis.clicked.connect(self.analysis)
self.btn_emotion.clicked.connect(self.emotionale_Analysis)
self.label_remark.setText(self.contact.remark)
self.stackedWidget.addWidget(self.view_userinfo)
self.stackedWidget.setCurrentWidget(self.view_userinfo)
menu = QMenu(self)
self.toDocxAct = QAction(Icon.ToDocx, '导出Docx', self)
self.toCSVAct = QAction(Icon.ToCSV, '导出CSV', self)
self.toHtmlAct = QAction(Icon.ToHTML, '导出HTML', self)
self.toTxtAct = QAction(Icon.ToTXT, '导出TXT', self)
self.toolButton_output.setPopupMode(QToolButton.MenuButtonPopup)
self.toolButton_output.clicked.connect(self.toolButton_show)
menu.addAction(self.toDocxAct)
menu.addAction(self.toCSVAct)
menu.addAction(self.toHtmlAct)
menu.addAction(self.toTxtAct)
self.toolButton_output.setMenu(menu)
self.toolButton_output.setIcon(Icon.Output)
# self.toolButton_output.addSeparator()
self.toHtmlAct.triggered.connect(self.output)
self.toDocxAct.triggered.connect(self.output)
self.toCSVAct.triggered.connect(self.output)
self.toTxtAct.triggered.connect(self.output)
def toolButton_show(self):
self.toolButton_output.showMenu()
def analysis(self):
QMessageBox.warning(self,
"别急别急",
"马上就实现该功能"
)
return
self.stackedWidget.setCurrentWidget(self.view_analysis)
if 'room' in self.contact.wxid:
QMessageBox.warning(
self, '警告',
'暂不支持群组'
)
return
self.view_analysis.start()
def annual_report(self):
# QMessageBox.warning(
# self,
# "提示",
# "敬请期待"
# )
# return
self.contact.save_avatar()
self.report_thread = ReportThread(self.contact)
self.report_thread.okSignal.connect(lambda x: QDesktopServices.openUrl(QUrl("http://127.0.0.1:21314")))
self.report_thread.start()
QDesktopServices.openUrl(QUrl("http://127.0.0.1:21314"))
def emotionale_Analysis(self):
QMessageBox.warning(self,
"别急别急",
"马上就实现该功能"
)
return
self.stackedWidget.setCurrentWidget(self.view_emotion)
if 'room' in self.contact.wxid:
QMessageBox.warning(
self, '警告',
'暂不支持群组'
)
return
self.view_emotion.start()
def back(self):
"""
将userinfo界面设置为可见其他界面设置为不可见
"""
self.stackedWidget.setCurrentWidget(self.view_userinfo)
def output(self):
"""
导出聊天记录
:return:
"""
self.stackedWidget.setCurrentWidget(self.view_userinfo)
if self.sender() == self.toDocxAct:
print('功能暂未实现')
QMessageBox.warning(self,
"别急别急",
"马上就实现该功能"
)
return
self.outputThread = Output(self.Me, self.contact.wxid)
elif self.sender() == self.toCSVAct:
# self.outputThread = Output(self.contact, type_=Output.CSV)
dialog = ExportDialog(self.contact,title='选择导出的消息类型', file_type='csv', parent=self)
result = dialog.exec_() # 使用exec_()获取用户的操作结果
elif self.sender() == self.toHtmlAct:
dialog = ExportDialog(self.contact,title='选择导出的消息类型', file_type='html', parent=self)
result = dialog.exec_() # 使用exec_()获取用户的操作结果
elif self.sender() == self.toTxtAct:
dialog = ExportDialog(self.contact, title='选择导出的消息类型', file_type='txt', parent=self)
result = dialog.exec_() # 使用exec_()获取用户的操作结果
def hide_progress_bar(self, int):
reply = QMessageBox(self)
reply.setIcon(QMessageBox.Information)
reply.setWindowTitle('OK')
reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)")
reply.addButton("确认", QMessageBox.AcceptRole)
reply.addButton("取消", QMessageBox.RejectRole)
api = reply.exec_()
self.view_userinfo.progressBar.setVisible(False)
def output_progress(self, value):
self.view_userinfo.progressBar.setProperty('value', value)
def set_progressBar_range(self, value):
self.view_userinfo.progressBar.setVisible(True)
self.view_userinfo.progressBar.setRange(0, value)
class ReportThread(QThread):
okSignal = pyqtSignal(bool)
def __init__(self, contact):
super().__init__()
self.contact = contact
def run(self):
from app.web_ui import web
web.contact = self.contact
web.run(port='21314')
self.okSignal.emit(True)

View File

@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'contactInfoUi.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, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(494, 748)
self.verticalLayout = QtWidgets.QVBoxLayout(Form)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setSpacing(0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label_remark = QtWidgets.QLabel(Form)
self.label_remark.setMaximumSize(QtCore.QSize(120, 100))
font = QtGui.QFont()
font.setPointSize(12)
self.label_remark.setFont(font)
self.label_remark.setText("")
self.label_remark.setObjectName("label_remark")
self.horizontalLayout_3.addWidget(self.label_remark)
self.btn_analysis = QtWidgets.QPushButton(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_analysis.sizePolicy().hasHeightForWidth())
self.btn_analysis.setSizePolicy(sizePolicy)
self.btn_analysis.setStyleSheet("")
self.btn_analysis.setFlat(False)
self.btn_analysis.setObjectName("btn_analysis")
self.horizontalLayout_3.addWidget(self.btn_analysis)
self.btn_emotion = QtWidgets.QPushButton(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_emotion.sizePolicy().hasHeightForWidth())
self.btn_emotion.setSizePolicy(sizePolicy)
self.btn_emotion.setFlat(False)
self.btn_emotion.setObjectName("btn_emotion")
self.horizontalLayout_3.addWidget(self.btn_emotion)
self.btn_report = QtWidgets.QPushButton(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_report.sizePolicy().hasHeightForWidth())
self.btn_report.setSizePolicy(sizePolicy)
self.btn_report.setFlat(False)
self.btn_report.setObjectName("btn_report")
self.horizontalLayout_3.addWidget(self.btn_report)
self.btn_back = QtWidgets.QPushButton(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_back.sizePolicy().hasHeightForWidth())
self.btn_back.setSizePolicy(sizePolicy)
self.btn_back.setFlat(False)
self.btn_back.setObjectName("btn_back")
self.horizontalLayout_3.addWidget(self.btn_back)
self.toolButton_output = QtWidgets.QToolButton(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.toolButton_output.sizePolicy().hasHeightForWidth())
self.toolButton_output.setSizePolicy(sizePolicy)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("../../data/icons/output.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_output.setIcon(icon)
self.toolButton_output.setCheckable(False)
self.toolButton_output.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
self.toolButton_output.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_output.setAutoRaise(True)
self.toolButton_output.setArrowType(QtCore.Qt.NoArrow)
self.toolButton_output.setObjectName("toolButton_output")
self.horizontalLayout_3.addWidget(self.toolButton_output)
self.horizontalLayout_3.setStretch(0, 1)
self.verticalLayout.addLayout(self.horizontalLayout_3)
self.stackedWidget = QtWidgets.QStackedWidget(Form)
self.stackedWidget.setObjectName("stackedWidget")
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
self.stackedWidget.addWidget(self.page_3)
self.page_4 = QtWidgets.QWidget()
self.page_4.setObjectName("page_4")
self.stackedWidget.addWidget(self.page_4)
self.verticalLayout.addWidget(self.stackedWidget)
self.retranslateUi(Form)
self.stackedWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.btn_analysis.setText(_translate("Form", "统计信息"))
self.btn_emotion.setText(_translate("Form", "情感分析"))
self.btn_report.setText(_translate("Form", "年度报告"))
self.btn_back.setText(_translate("Form", "退出"))
self.toolButton_output.setText(_translate("Form", "导出聊天记录"))

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'contactUi.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(6)
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-radius:5px;\n"
"border-top: 0px solid #b2e281;\n"
"border-bottom: 0px solid #b2e281;\n"
"border-right: 0px solid #b2e281;\n"
"border-left: 0px solid #b2e281;\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.setMinimumSize(QtCore.QSize(30, 0))
self.label_2.setMaximumSize(QtCore.QSize(30, 16777215))
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"))

View File

@ -0,0 +1,155 @@
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QLineEdit
from app.DataBase import micro_msg_db, misc_db
from app.components import ContactQListWidgetItem
from app.person import ContactPC
from app.ui.Icon import Icon
from .contactInfo import ContactInfo
from .contactUi import Ui_Form
from ...util import search
# 美化样式表
Stylesheet = """
QPushButton{
background-color: transparent;
}
QPushButton:hover {
background-color: lightgray;
}
/*去掉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 ContactWindow(QWidget, Ui_Form):
load_finish_signal = pyqtSignal(bool)
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.contacts = [[], []]
self.show_contacts()
def init_ui(self):
search_action = QAction(self.lineEdit)
search_action.setIcon(Icon.Search_Icon)
self.lineEdit.addAction(search_action, QLineEdit.LeadingPosition)
self.lineEdit.returnPressed.connect(self.search_contact)
self.listWidget.clear()
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
self.listWidget.setCurrentRow(0)
self.stackedWidget.setCurrentIndex(0)
def show_contacts(self):
# return
if self.ok_flag:
return
micro_msg_db.init_database()
if not micro_msg_db.open_flag:
QMessageBox.critical(self, "错误", "数据库不存在\n请先解密数据库")
self.show_thread = ShowThread()
self.show_thread.showSingal.connect(self.show_contact)
self.show_thread.load_finish_signal.connect(self.load_finish_signal)
self.show_thread.start()
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 search_contact(self):
keyword = self.lineEdit.text()
if keyword:
index = search.search_by_content(keyword, self.contacts)
self.listWidget.setCurrentRow(index)
self.stackedWidget.setCurrentIndex(index)
def show_contact(self, contact: ContactPC):
self.contacts[0].append(contact.remark)
self.contacts[1].append(contact.nickName)
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)
self.stackedWidget.setCurrentIndex(row)
class ShowContactThread(QThread):
showSingal = pyqtSignal(ContactPC)
load_finish_signal = pyqtSignal(bool)
# heightSingal = pyqtSignal(int)
def __init__(self):
super().__init__()
def run(self) -> None:
contact_info_lists = micro_msg_db.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_db.get_avatar_buffer(contact.wxid)
contact.set_avatar(contact.smallHeadImgBLOG)
self.showSingal.emit(contact)
# pprint(contact.__dict__)
self.load_finish_signal.emit(True)
class ShowThread(QThread):
showSingal = pyqtSignal(ContactPC)
load_finish_signal = pyqtSignal(bool)
# heightSingal = pyqtSignal(int)
def __init__(self):
super().__init__()
def run(self) -> None:
QThread.sleep(1)
self.load_finish_signal.emit(True)

View File

@ -0,0 +1,105 @@
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \
QProgressBar, QLabel, QMessageBox
from app.DataBase.output_pc import Output
types = {
'文本': 1,
'图片': 3,
'语音': 34,
'视频': 43,
'表情包': 47,
'拍一拍等系统消息': 10000
}
Stylesheet = """
QPushButton{
background-color: #ffffff;
}
QPushButton:hover {
background-color: lightgray;
}
"""
class ExportDialog(QDialog):
def __init__(self, contact=None, title="选择导出的类型", file_type="csv", parent=None):
super(ExportDialog, self).__init__(parent)
self.setStyleSheet(Stylesheet)
self.contact = contact
if file_type == 'html':
self.export_type = Output.HTML
self.export_choices = {"文本": True, "图片": True, "语音": True, "视频": True, "表情包": True,
'拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择
elif file_type == 'csv':
self.export_type = Output.CSV
self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
elif file_type == 'txt':
self.export_type = Output.TXT
self.export_choices = {"文本": True, "图片": True, "语音": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
else:
self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
self.setWindowTitle(title)
layout = QVBoxLayout(self)
self.resize(400, 300)
self.worker = None # 导出线程
self.progress_bar = QProgressBar(self)
self.progress_label = QLabel(self)
for export_type, default_state in self.export_choices.items():
checkbox = QCheckBox(export_type)
checkbox.setChecked(default_state)
layout.addWidget(checkbox)
layout.addWidget(self.progress_bar)
layout.addWidget(self.progress_label)
hlayout = QHBoxLayout(self)
self.export_button = QPushButton("导出")
self.export_button.clicked.connect(self.export_data)
hlayout.addWidget(self.export_button)
self.cancel_button = QPushButton("取消")
self.cancel_button.clicked.connect(self.reject) # 使用reject关闭对话框
hlayout.addWidget(self.cancel_button)
layout.addLayout(hlayout)
self.setLayout(layout)
def export_data(self):
self.export_button.setEnabled(False)
self.cancel_button.setEnabled(False)
# 在这里获取用户选择的导出数据类型
selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in
zip(self.export_choices.keys(), self.findChildren(QCheckBox))}
# 在这里根据用户选择的数据类型执行导出操作
print("选择的数据类型:", selected_types)
self.worker = Output(self.contact, type_=self.export_type, message_types=selected_types)
self.worker.progressSignal.connect(self.update_progress)
self.worker.okSignal.connect(self.export_finished)
self.worker.start()
# self.accept() # 使用accept关闭对话框
def export_finished(self):
self.export_button.setEnabled(True)
self.cancel_button.setEnabled(True)
reply = QMessageBox(self)
reply.setIcon(QMessageBox.Information)
reply.setWindowTitle('OK')
reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)")
reply.addButton("确认", QMessageBox.AcceptRole)
reply.addButton("取消", QMessageBox.RejectRole)
api = reply.exec_()
self.accept()
def update_progress(self, progress_percentage):
self.progress_bar.setValue(progress_percentage)
self.progress_label.setText(f"导出进度: {progress_percentage}%")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
dialog = ExportDialog()
result = dialog.exec_() # 使用exec_()获取用户的操作结果
if result == QDialog.Accepted:
print("用户点击了导出按钮")
else:
print("用户点击了取消按钮")
sys.exit(app.exec_())

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
"""
@File : __init__.py.py
@Author : Shuaikang Zhou
@Time : 2022/12/24 10:34
@IDE : Pycharm
@Version : Python3.10
@comment : ···
"""

View File

@ -0,0 +1,15 @@
from PyQt5.QtWidgets import *
from .userinfoUi import Ui_Frame
class UserinfoController(QWidget, Ui_Frame):
def __init__(self, contact, parent=None):
super().__init__(parent)
self.setupUi(self)
self.l_remark.setText(contact.remark)
self.l_avatar.setPixmap(contact.avatar)
self.l_nickname.setText(f'昵称:{contact.nickName}')
self.l_username.setText(f'微信号:{contact.alias}')
self.lineEdit.setText(contact.remark)
self.progressBar.setVisible(False)

View File

@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'userinfoUi.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, QtGui, QtWidgets
class Ui_Frame(object):
def setupUi(self, Frame):
Frame.setObjectName("Frame")
Frame.resize(624, 720)
Frame.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor))
Frame.setMouseTracking(True)
Frame.setTabletTracking(True)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(Frame)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setHorizontalSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.l_avatar = QtWidgets.QLabel(Frame)
self.l_avatar.setMinimumSize(QtCore.QSize(80, 80))
self.l_avatar.setMaximumSize(QtCore.QSize(80, 80))
self.l_avatar.setText("")
self.l_avatar.setPixmap(QtGui.QPixmap("../../../a_img/be0fa6c0c4707fb5f7b37b660de826d3.jpg"))
self.l_avatar.setScaledContents(True)
self.l_avatar.setObjectName("l_avatar")
self.gridLayout.addWidget(self.l_avatar, 0, 0, 3, 1)
self.l_remark = QtWidgets.QLabel(Frame)
self.l_remark.setMinimumSize(QtCore.QSize(0, 30))
self.l_remark.setMaximumSize(QtCore.QSize(16777215, 30))
font = QtGui.QFont()
font.setPointSize(15)
self.l_remark.setFont(font)
self.l_remark.setObjectName("l_remark")
self.gridLayout.addWidget(self.l_remark, 0, 1, 1, 1)
self.l_nickname = QtWidgets.QLabel(Frame)
self.l_nickname.setMinimumSize(QtCore.QSize(0, 30))
self.l_nickname.setMaximumSize(QtCore.QSize(16777215, 30))
self.l_nickname.setObjectName("l_nickname")
self.gridLayout.addWidget(self.l_nickname, 1, 1, 1, 1)
self.l_username = QtWidgets.QLabel(Frame)
self.l_username.setMinimumSize(QtCore.QSize(0, 20))
self.l_username.setMaximumSize(QtCore.QSize(16777215, 20))
self.l_username.setObjectName("l_username")
self.gridLayout.addWidget(self.l_username, 2, 1, 1, 1)
self.gridLayout.setRowStretch(0, 1)
self.gridLayout.setRowStretch(1, 1)
self.gridLayout.setRowStretch(2, 1)
self.verticalLayout.addLayout(self.gridLayout)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem2)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(Frame)
self.label.setMinimumSize(QtCore.QSize(80, 0))
self.label.setMaximumSize(QtCore.QSize(80, 16777215))
font = QtGui.QFont()
font.setPointSize(15)
self.label.setFont(font)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(Frame)
self.lineEdit.setMinimumSize(QtCore.QSize(0, 25))
self.lineEdit.setMaximumSize(QtCore.QSize(16777215, 25))
font = QtGui.QFont()
font.setPointSize(15)
self.lineEdit.setFont(font)
self.lineEdit.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.lineEdit.setAutoFillBackground(False)
self.lineEdit.setStyleSheet("\n"
" background:transparent;border-width:0;border-style:outset\n"
" ")
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.verticalLayout.addLayout(self.horizontalLayout)
spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem3)
self.progressBar = QtWidgets.QProgressBar(Frame)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.verticalLayout.addWidget(self.progressBar)
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem4)
self.verticalLayout.setStretch(0, 2)
self.verticalLayout.setStretch(1, 3)
self.verticalLayout.setStretch(2, 4)
self.verticalLayout.setStretch(3, 1)
self.verticalLayout.setStretch(4, 4)
self.verticalLayout.setStretch(5, 1)
self.verticalLayout.setStretch(6, 2)
self.horizontalLayout_2.addLayout(self.verticalLayout)
spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem5)
self.horizontalLayout_2.setStretch(0, 1)
self.horizontalLayout_2.setStretch(1, 2)
self.horizontalLayout_2.setStretch(2, 1)
self.horizontalLayout_3.addLayout(self.horizontalLayout_2)
self.retranslateUi(Frame)
QtCore.QMetaObject.connectSlotsByName(Frame)
def retranslateUi(self, Frame):
_translate = QtCore.QCoreApplication.translate
Frame.setWindowTitle(_translate("Frame", "Frame"))
self.l_remark.setText(_translate("Frame", "曹雨萱"))
self.l_nickname.setText(_translate("Frame", "昵称997"))
self.l_username.setText(_translate("Frame", "账号TextLabel"))
self.label.setText(_translate("Frame", "备注名"))
self.lineEdit.setText(_translate("Frame", "曹雨萱"))

250
app/ui/mainview.py Normal file
View File

@ -0,0 +1,250 @@
# -*- coding: utf-8 -*-
"""
@File : mainview.py
@Author : Shuaikang Zhou
@Time : 2022/12/13 15:07
@IDE : Pycharm
@Version : Python3.10
@comment : 主窗口
"""
import json
import os.path
from PyQt5.QtCore import pyqtSignal, QUrl, Qt, QThread, QSize
from PyQt5.QtGui import QPixmap, QFont, QDesktopServices
from PyQt5.QtWidgets import QMainWindow, QLabel, QListWidgetItem, QMessageBox
from app import config
from app.DataBase import msg_db, misc_db, micro_msg_db, hard_link_db
from app.ui.Icon import Icon
from . import mainwindow
from .chat import ChatWindow
from .contact import ContactWindow
from .tool.tool_window import ToolWindow
from ..DataBase.output_pc import Output
from ..person import MePC
# 美化样式表
Stylesheet = """
/*去掉item虚线边框*/
QListWidget, QListView, QTreeWidget, QTreeView {
outline: 0px;
}
/*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/
QListWidget {
min-width: 120px;
max-width: 120px;
color: black;
background: white;
border:none;
}
QListWidget::item{
height:60;
}
/*被选中时的背景颜色和左边框颜色*/
QListWidget::item:selected {
background: rgb(204, 204, 204);
border-left: 4px solid rgb(9, 187, 7);
color: black;
font-weight: bold;
}
/*鼠标悬停颜色*/
HistoryPanel::item:hover {
background: rgb(52, 52, 52);
}
"""
class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
exitSignal = pyqtSignal(bool)
okSignal = pyqtSignal(bool)
# username = ''
def __init__(self, username, parent=None):
super(MainWinController, self).__init__(parent)
self.outputThread0 = None
self.outputThread = None
self.setupUi(self)
self.setWindowIcon(Icon.MainWindow_Icon)
self.setStyleSheet(Stylesheet)
self.listWidget.clear()
self.resize(QSize(800, 600))
self.action_desc.triggered.connect(self.about)
self.load_flag = False
self.load_data()
self.load_num = 0
self.label = QLabel(self)
self.label.setGeometry((self.width() - 300) // 2, (self.height() - 100) // 2, 300, 100)
self.label.setPixmap(QPixmap(':/icons/icons/loading.svg'))
def load_data(self, flag=True):
if os.path.exists('./app/data/info.json'):
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()
me.wxid = dic.get('wxid')
me.name = dic.get('name')
me.mobile = dic.get('mobile')
me.wx_dir = dic.get('wx_dir')
self.set_my_info(wxid)
self.load_flag = True
else:
QMessageBox.information(
self,
'温馨提示',
'点击 工具->获取信息 重启后可以显示本人头像哦'
)
def init_ui(self):
self.menu_output.setIcon(Icon.Output)
self.action_output_CSV.setIcon(Icon.ToCSV)
self.action_output_CSV.triggered.connect(self.output)
self.action_output_contacts.setIcon(Icon.Output)
self.action_output_contacts.triggered.connect(self.output)
self.action_desc.setIcon(Icon.Help_Icon)
self.action_help_contact.triggered.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/5")))
self.action_help_chat.triggered.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/5")))
self.action_help_decrypt.triggered.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/4")))
self.listWidget.setVisible(False)
self.stackedWidget.setVisible(False)
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
tool_item = QListWidgetItem(Icon.Tool_Icon, '工具', self.listWidget)
chat_item = QListWidgetItem(Icon.Chat_Icon, '聊天', self.listWidget)
contact_item = QListWidgetItem(Icon.Contact_Icon, '好友', self.listWidget)
myinfo_item = QListWidgetItem(Icon.Home_Icon, '我的', self.listWidget)
tool_window = ToolWindow()
tool_window.get_info_signal.connect(self.set_my_info)
tool_window.decrypt_success_signal.connect(self.decrypt_success)
tool_window.load_finish_signal.connect(self.loading)
self.stackedWidget.addWidget(tool_window)
self.chat_window = ChatWindow()
# chat_window = QWidget()
self.stackedWidget.addWidget(self.chat_window)
self.contact_window = ContactWindow()
self.stackedWidget.addWidget(self.contact_window)
label = QLabel('该功能暂不支持哦')
label.setFont(QFont("微软雅黑", 50))
label.setAlignment(Qt.AlignCenter)
self.stackedWidget.addWidget(label)
tool_window.load_finish_signal.connect(self.loading)
self.statusbar.showMessage('聊天窗口上划到顶部会加载新的聊天记录\n一次不行那就多来几次')
self.contact_window.load_finish_signal.connect(self.loading)
self.chat_window.load_finish_signal.connect(self.loading)
def setCurrentIndex(self, row):
self.stackedWidget.setCurrentIndex(row)
if row == 2:
self.stackedWidget.currentWidget().show_contacts()
if row == 1:
self.stackedWidget.currentWidget().show_chats()
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()
try:
img_bytes = misc_db.get_avatar_buffer(wxid)
except AttributeError:
return
if not img_bytes:
return
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 stop_loading(self, a0):
self.label.setVisible(False)
def loading(self, a0):
self.load_num += 1
# self.label.setVisible(False)
print('加载一个了')
if self.load_num == 1:
print('ok了')
self.label.clear()
self.label.hide()
self.okSignal.emit(True)
self.listWidget.setVisible(True)
self.stackedWidget.setVisible(True)
if self.load_flag:
self.listWidget.setCurrentRow(1)
self.stackedWidget.setCurrentIndex(1)
else:
self.listWidget.setCurrentRow(0)
self.stackedWidget.setCurrentIndex(0)
def output(self):
if self.sender() == self.action_output_CSV:
self.outputThread = Output(None, type_=Output.CSV_ALL)
self.outputThread.okSignal.connect(
lambda x: self.message('聊天记录导出成功'))
self.outputThread.start()
elif self.sender() == self.action_output_contacts:
self.outputThread = Output(None, type_=Output.CONTACT_CSV)
self.outputThread.okSignal.connect(
lambda x: self.message('联系人导出成功'))
self.outputThread.start()
def message(self, msg):
QMessageBox.about(self, "提醒", msg)
def about(self):
"""
关于
"""
QMessageBox.about(self, "关于",
f'''版本:{config.version}<br>QQ交流群:{config.contact}<br>地址:<a href='https://github.com/LC044/WeChatMsg'>https://github.com/LC044/WeChatMsg</a><br>新特性:<br>{''.join(['' + i for i in config.description])}
'''
)
def decrypt_success(self):
QMessageBox.about(self, "解密成功", "请重新启动")
self.close()
def close(self) -> bool:
super().close()
misc_db.close()
msg_db.close()
micro_msg_db.close()
hard_link_db.close()
self.contact_window.close()
self.exitSignal.emit(True)
class LoadWindowThread(QThread):
okSignal = pyqtSignal(bool)
def __init__(self):
super().__init__()
self.num = 0
def loading(self):
self.num += 1
print('加载一个了')
if self.num == 2:
self.okSignal.emit(True)
def run(self):
self.chat_window = ChatWindow()
self.contact_window = ContactWindow()
self.contact_window.load_finish_signal.connect(self.loading)
self.chat_window.load_finish_signal.connect(self.loading)
print('加载完成')
self.okSignal.emit(True)

179
app/ui/mainwindow.py Normal file
View File

@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainwindow.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, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setStyleSheet("\n"
" /*去掉item虚线边框*/\n"
" QListWidget, QListView, QTreeWidget, QTreeView {\n"
" outline: 0px;\n"
" }\n"
" /*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/\n"
" QListWidget {\n"
" min-width: 120px;\n"
" max-width: 120px;\n"
" color: black;\n"
" background: white;\n"
" border:none;\n"
" }\n"
" QListWidget::item{\n"
" height:80;\n"
" }\n"
" /*被选中时的背景颜色和左边框颜色*/\n"
" QListWidget::item:selected {\n"
" background: rgb(204, 204, 204);\n"
" border-left: 4px solid rgb(9, 187, 7);\n"
" }\n"
" /*鼠标悬停颜色*/\n"
" HistoryPanel::item:hover {\n"
" background: rgb(52, 52, 52);\n"
" }\n"
" ")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.frame_info = QtWidgets.QFrame(self.centralwidget)
self.frame_info.setMinimumSize(QtCore.QSize(80, 500))
self.frame_info.setMaximumSize(QtCore.QSize(80, 16777215))
self.frame_info.setStyleSheet("background-color:rgb(240,240,240)")
self.frame_info.setFrameShape(QtWidgets.QFrame.NoFrame)
self.frame_info.setFrameShadow(QtWidgets.QFrame.Plain)
self.frame_info.setObjectName("frame_info")
self.myavatar = QtWidgets.QLabel(self.frame_info)
self.myavatar.setGeometry(QtCore.QRect(10, 40, 60, 60))
self.myavatar.setObjectName("myavatar")
self.listWidget = QtWidgets.QListWidget(self.frame_info)
self.listWidget.setGeometry(QtCore.QRect(0, 230, 120, 331))
self.listWidget.setMinimumSize(QtCore.QSize(120, 0))
self.listWidget.setMaximumSize(QtCore.QSize(120, 16777215))
self.listWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.listWidget.setObjectName("listWidget")
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
self.horizontalLayout.addWidget(self.frame_info)
self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
font = QtGui.QFont()
font.setFamily("微软雅黑")
font.setBold(False)
font.setWeight(50)
self.stackedWidget.setFont(font)
self.stackedWidget.setObjectName("stackedWidget")
self.horizontalLayout.addWidget(self.stackedWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 23))
self.menubar.setObjectName("menubar")
self.menu_F = QtWidgets.QMenu(self.menubar)
self.menu_F.setObjectName("menu_F")
self.menu_data = QtWidgets.QMenu(self.menubar)
font = QtGui.QFont()
font.setFamily("微软雅黑")
self.menu_data.setFont(font)
self.menu_data.setObjectName("menu_data")
self.menu_output = QtWidgets.QMenu(self.menu_data)
self.menu_output.setObjectName("menu_output")
self.menu_2 = QtWidgets.QMenu(self.menubar)
self.menu_2.setObjectName("menu_2")
self.menu_about = QtWidgets.QMenu(self.menubar)
self.menu_about.setObjectName("menu_about")
self.menu_3 = QtWidgets.QMenu(self.menubar)
self.menu_3.setObjectName("menu_3")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.action_3 = QtWidgets.QAction(MainWindow)
self.action_3.setObjectName("action_3")
self.action_4 = QtWidgets.QAction(MainWindow)
self.action_4.setObjectName("action_4")
self.action_help_decrypt = QtWidgets.QAction(MainWindow)
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
self.action_help_decrypt.setFont(font)
self.action_help_decrypt.setObjectName("action_help_decrypt")
self.action_desc = QtWidgets.QAction(MainWindow)
self.action_desc.setObjectName("action_desc")
self.action_help_chat = QtWidgets.QAction(MainWindow)
self.action_help_chat.setObjectName("action_help_chat")
self.action_help_contact = QtWidgets.QAction(MainWindow)
self.action_help_contact.setObjectName("action_help_contact")
self.action_output_CSV = QtWidgets.QAction(MainWindow)
self.action_output_CSV.setObjectName("action_output_CSV")
self.action_output_contacts = QtWidgets.QAction(MainWindow)
self.action_output_contacts.setObjectName("action_output_contacts")
self.menu_F.addSeparator()
self.menu_F.addSeparator()
self.menu_F.addAction(self.action_3)
self.menu_F.addAction(self.action_4)
self.menu_output.addAction(self.action_output_CSV)
self.menu_data.addAction(self.menu_output.menuAction())
self.menu_data.addAction(self.action_output_contacts)
self.menu_2.addAction(self.action_help_decrypt)
self.menu_2.addAction(self.action_help_chat)
self.menu_2.addAction(self.action_help_contact)
self.menu_about.addAction(self.action_desc)
self.menubar.addAction(self.menu_F.menuAction())
self.menubar.addAction(self.menu_data.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menu_about.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.myavatar.setText(_translate("MainWindow", "avatar"))
__sortingEnabled = self.listWidget.isSortingEnabled()
self.listWidget.setSortingEnabled(False)
item = self.listWidget.item(0)
item.setText(_translate("MainWindow", "新建项目"))
item = self.listWidget.item(1)
item.setText(_translate("MainWindow", "新建项目"))
item = self.listWidget.item(2)
item.setText(_translate("MainWindow", "新建项目"))
item = self.listWidget.item(3)
item.setText(_translate("MainWindow", "新建项目"))
item = self.listWidget.item(4)
item.setText(_translate("MainWindow", "新建项目"))
self.listWidget.setSortingEnabled(__sortingEnabled)
self.menu_F.setTitle(_translate("MainWindow", "文件(F)"))
self.menu_data.setTitle(_translate("MainWindow", "数据"))
self.menu_output.setTitle(_translate("MainWindow", "导出聊天记录(全部)"))
self.menu_2.setTitle(_translate("MainWindow", "帮助"))
self.menu_about.setTitle(_translate("MainWindow", "关于"))
self.menu_3.setTitle(_translate("MainWindow", "不显示或者显示异常请重启应用、没反应那就多等一会儿"))
self.action_3.setText(_translate("MainWindow", "保存"))
self.action_4.setText(_translate("MainWindow", "退出"))
self.action_help_decrypt.setText(_translate("MainWindow", "解密教程"))
self.action_desc.setText(_translate("MainWindow", "说明"))
self.action_help_chat.setText(_translate("MainWindow", "聊天相关"))
self.action_help_contact.setText(_translate("MainWindow", "好友相关"))
self.action_output_CSV.setText(_translate("MainWindow", "CSV"))
self.action_output_contacts.setText(_translate("MainWindow", "导出联系人"))

1
app/ui/tool/__init__.py Normal file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,3 @@
from .pc_decrypt import DecryptControl
__all__ = ['DecryptControl']

View File

@ -0,0 +1,197 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'decryptUi.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, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(611, 519)
font = QtGui.QFont()
font.setFamily("微软雅黑")
Dialog.setFont(font)
Dialog.setLayoutDirection(QtCore.Qt.LeftToRight)
self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_4.addItem(spacerItem)
self.btn_help = QtWidgets.QPushButton(Dialog)
self.btn_help.setMaximumSize(QtCore.QSize(200, 16777215))
self.btn_help.setObjectName("btn_help")
self.horizontalLayout_4.addWidget(self.btn_help)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_4.addItem(spacerItem1)
self.verticalLayout_2.addLayout(self.horizontalLayout_4)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem2)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem3)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label_3 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setFamily("一纸情书")
font.setPointSize(20)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.label_9 = QtWidgets.QLabel(Dialog)
self.label_9.setAlignment(QtCore.Qt.AlignCenter)
self.label_9.setObjectName("label_9")
self.verticalLayout.addWidget(self.label_9)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.label_phone = QtWidgets.QLabel(Dialog)
self.label_phone.setText("")
self.label_phone.setObjectName("label_phone")
self.gridLayout.addWidget(self.label_phone, 2, 1, 1, 1)
self.label_7 = QtWidgets.QLabel(Dialog)
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;\n"
"\n"
" border-radius:5px;\n"
" border-top: 0px solid #b2e281;\n"
" border-bottom: 2px solid black;\n"
" border-right: 0px solid #b2e281;\n"
" border-left: 0px solid #b2e281;\n"
"\n"
"\n"
" border-style:outset\n"
" ")
self.lineEdit.setFrame(False)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1)
self.label_5 = QtWidgets.QLabel(Dialog)
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 3, 0, 1, 1)
self.label_6 = QtWidgets.QLabel(Dialog)
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(400, 16777215))
self.label_key.setText("")
self.label_key.setObjectName("label_key")
self.gridLayout.addWidget(self.label_key, 5, 1, 1, 1)
self.label = QtWidgets.QLabel(Dialog)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label_pid = QtWidgets.QLabel(Dialog)
self.label_pid.setText("")
self.label_pid.setObjectName("label_pid")
self.gridLayout.addWidget(self.label_pid, 0, 1, 1, 1)
self.label_name = QtWidgets.QLabel(Dialog)
self.label_name.setText("")
self.label_name.setObjectName("label_name")
self.gridLayout.addWidget(self.label_name, 3, 1, 1, 1)
self.label_4 = QtWidgets.QLabel(Dialog)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
self.label_version = QtWidgets.QLabel(Dialog)
self.label_version.setText("")
self.label_version.setObjectName("label_version")
self.gridLayout.addWidget(self.label_version, 1, 1, 1, 1)
self.label_8 = QtWidgets.QLabel(Dialog)
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(400, 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)
self.gridLayout.setColumnMinimumWidth(0, 1)
self.gridLayout.setColumnStretch(0, 1)
self.gridLayout.setColumnStretch(1, 10)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 2, 1)
self.btn_getinfo = QtWidgets.QPushButton(Dialog)
self.btn_getinfo.setMinimumSize(QtCore.QSize(0, 60))
self.btn_getinfo.setObjectName("btn_getinfo")
self.gridLayout_2.addWidget(self.btn_getinfo, 0, 1, 1, 1)
self.checkBox = QtWidgets.QCheckBox(Dialog)
self.checkBox.setText("")
self.checkBox.setObjectName("checkBox")
self.gridLayout_2.addWidget(self.checkBox, 0, 2, 1, 1)
self.btn_db_dir = QtWidgets.QPushButton(Dialog)
self.btn_db_dir.setMinimumSize(QtCore.QSize(0, 60))
self.btn_db_dir.setObjectName("btn_db_dir")
self.gridLayout_2.addWidget(self.btn_db_dir, 1, 1, 1, 1)
self.checkBox_2 = QtWidgets.QCheckBox(Dialog)
self.checkBox_2.setText("")
self.checkBox_2.setObjectName("checkBox_2")
self.gridLayout_2.addWidget(self.checkBox_2, 1, 2, 1, 1)
self.verticalLayout.addLayout(self.gridLayout_2)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem4)
self.pushButton_3 = QtWidgets.QPushButton(Dialog)
self.pushButton_3.setMinimumSize(QtCore.QSize(0, 60))
self.pushButton_3.setMaximumSize(QtCore.QSize(100, 16777215))
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout_2.addWidget(self.pushButton_3)
self.label_tip = QtWidgets.QLabel(Dialog)
self.label_tip.setObjectName("label_tip")
self.horizontalLayout_2.addWidget(self.label_tip)
spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem5)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_ready = QtWidgets.QLabel(Dialog)
self.label_ready.setObjectName("label_ready")
self.horizontalLayout.addWidget(self.label_ready)
self.progressBar = QtWidgets.QProgressBar(Dialog)
self.progressBar.setProperty("value", 50)
self.progressBar.setObjectName("progressBar")
self.horizontalLayout.addWidget(self.progressBar)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_3.addLayout(self.verticalLayout)
spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem6)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
spacerItem7 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem7)
self.verticalLayout_3.addLayout(self.verticalLayout_2)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.btn_help.setText(_translate("Dialog", "使用说明"))
self.label_3.setText(_translate("Dialog", "解密数据库"))
self.label_9.setText(_translate("Dialog", "以下内容为自动获取,如获取失败请手动填写"))
self.label_7.setText(_translate("Dialog", "版本"))
self.label_5.setText(_translate("Dialog", "微信昵称"))
self.label_6.setText(_translate("Dialog", "密钥"))
self.label.setText(_translate("Dialog", "PID"))
self.label_2.setText(_translate("Dialog", "手机号"))
self.label_4.setText(_translate("Dialog", "wxid"))
self.label_8.setText(_translate("Dialog", "微信路径"))
self.btn_getinfo.setText(_translate("Dialog", "获取信息"))
self.btn_db_dir.setText(_translate("Dialog", "设置微信路径"))
self.pushButton_3.setText(_translate("Dialog", "开始启动"))
self.label_tip.setText(_translate("Dialog", "TextLabel"))
self.label_ready.setText(_translate("Dialog", "未就绪"))

View File

@ -0,0 +1,258 @@
import json
import os.path
import time
import traceback
from PyQt5.QtCore import pyqtSignal, QThread, QUrl, QFile, QIODevice, QTextStream
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
from app.DataBase import msg_db, misc_db
from app.DataBase.merge import merge_databases, merge_MediaMSG_databases
from app.decrypt import get_wx_info, decrypt
from app.log import logger
from app.util import path
from . import decryptUi
class DecryptControl(QWidget, decryptUi.Ui_Dialog):
DecryptSignal = pyqtSignal(bool)
get_wxidSignal = pyqtSignal(str)
def __init__(self, parent=None):
super(DecryptControl, self).__init__(parent)
self.setupUi(self)
self.pushButton_3.clicked.connect(self.decrypt)
self.btn_getinfo.clicked.connect(self.get_info)
self.btn_db_dir.clicked.connect(self.select_db_dir)
self.lineEdit.returnPressed.connect(self.set_wxid)
self.lineEdit.textChanged.connect(self.set_wxid_)
self.btn_help.clicked.connect(self.show_help)
self.label_tip.setVisible(False)
self.info = {}
self.lineEdit.setFocus()
self.ready = False
self.wx_dir = None
def show_help(self):
# 定义网页链接
url = QUrl("https://blog.lc044.love/post/4")
# 使用QDesktopServices打开网页
QDesktopServices.openUrl(url)
# @log
def get_info(self):
try:
file = QFile(':/data/version_list.json')
if file.open(QIODevice.ReadOnly | QIODevice.Text):
stream = QTextStream(file)
content = stream.readAll()
file.close()
VERSION_LIST = json.loads(content)
else:
return
result = get_wx_info.get_info(VERSION_LIST)
print(result)
if result == -1:
QMessageBox.critical(self, "错误", "请登录微信")
elif result == -2:
QMessageBox.critical(self, "错误", "微信版本不匹配\n请更新微信版本为:3.9.8.15")
elif result == -3:
QMessageBox.critical(self, "错误", "WeChat WeChatWin.dll Not Found")
else:
self.ready = True
self.info = result[0]
self.label_key.setText(self.info['key'])
self.lineEdit.setText(self.info['wxid'])
self.label_name.setText(self.info['name'])
self.label_phone.setText(self.info['mobile'])
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'])
directory = os.path.join(path.wx_path(), self.info['wxid'])
if os.path.exists(directory):
self.label_db_dir.setText(directory)
self.wx_dir = directory
self.checkBox_2.setChecked(True)
self.ready = True
if self.ready:
self.label_ready.setText('已就绪')
if self.wx_dir and os.path.exists(os.path.join(self.wx_dir)):
self.label_ready.setText('已就绪')
except Exception as e:
QMessageBox.critical(self, "未知错误", "请收集报错信息发起issue解决问题")
logger.error(traceback.format_exc())
def set_wxid_(self):
self.info['wxid'] = self.lineEdit.text()
def set_wxid(self):
self.info['wxid'] = self.lineEdit.text()
QMessageBox.information(self, "ok", f"wxid修改成功{self.info['wxid']}")
def select_db_dir(self):
directory = QFileDialog.getExistingDirectory(
self, "选取微信文件保存目录——能看到Msg文件夹",
path.wx_path()
) # 起始路径
db_dir = os.path.join(directory, 'Msg')
if not os.path.exists(db_dir):
QMessageBox.critical(self, "错误", "文件夹选择错误\n一般以wxid_xxx结尾")
return
self.label_db_dir.setText(directory)
self.wx_dir = directory
self.checkBox_2.setChecked(True)
if self.ready:
self.label_ready.setText('已就绪')
def decrypt(self):
if not self.ready:
QMessageBox.critical(self, "错误", "请先获取密钥")
return
if not self.wx_dir:
QMessageBox.critical(self, "错误", "请先选择微信安装路径")
return
if self.lineEdit.text() == 'None':
QMessageBox.critical(self, "错误", "请填入wxid")
return
db_dir = os.path.join(self.wx_dir, 'Msg')
if self.ready:
if not os.path.exists(db_dir):
QMessageBox.critical(self, "错误", "文件夹选择错误\n一般以wxid_xxx结尾")
return
if self.info.get('key') == 'none':
QMessageBox.critical(self, "错误", "密钥错误\n请检查微信版本是否为最新和微信路径是否正确")
self.label_tip.setVisible(True)
self.label_tip.setText('点我之后没有反应那就多等儿吧,不要再点了')
self.thread2 = DecryptThread(db_dir, self.info['key'])
self.thread2.maxNumSignal.connect(self.setProgressBarMaxNum)
self.thread2.signal.connect(self.progressBar_view)
self.thread2.okSignal.connect(self.btnExitClicked)
self.thread2.errorSignal.connect(
lambda x: QMessageBox.critical(self, "错误", "密钥错误\n请检查微信版本是否为最新和微信路径是否正确")
)
self.thread2.start()
def btnEnterClicked(self):
# print("enter clicked")
# 中间可以添加处理逻辑
# QMessageBox.about(self, "解密成功", "数据库文件存储在app/DataBase/Msg文件夹下")
self.DecryptSignal.emit(True)
# self.close()
def setProgressBarMaxNum(self, max_val):
self.progressBar.setRange(0, max_val)
def progressBar_view(self, value):
"""
进度条显示
:param value: 进度0-100
:return: None
"""
self.progressBar.setProperty('value', value)
# self.btnExitClicked()
# data.init_database()
def btnExitClicked(self):
# print("Exit clicked")
dic = {
'wxid': self.info['wxid'],
'wx_dir': self.wx_dir,
'name': self.info['name'],
'mobile': self.info['mobile']
}
try:
os.makedirs('./app/data', exist_ok=True)
with open('./app/data/info.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(dic))
except:
with open('./info.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(dic))
# 目标数据库文件
target_database = "app/DataBase/Msg/MSG.db"
# 源数据库文件列表
source_databases = [f"app/DataBase/Msg/MSG{i}.db" for i in range(1, 200)]
import shutil
shutil.copy2("app/DataBase/Msg/MSG0.db", target_database) # 使用一个数据库文件作为模板
# 合并数据库
try:
merge_databases(source_databases, target_database)
except FileNotFoundError:
QMessageBox.critical(self, "错误", "数据库不存在\n请检查微信版本是否为最新")
# 音频数据库文件
target_database = "app/DataBase/Msg/MediaMSG.db"
# 源数据库文件列表
source_databases = [f"app/DataBase/Msg/MediaMSG{i}.db" for i in range(1, 20)]
shutil.copy2("app/DataBase/Msg/MediaMSG0.db", target_database) # 使用一个数据库文件作为模板
# 合并数据库
try:
merge_MediaMSG_databases(source_databases, target_database)
except FileNotFoundError:
QMessageBox.critical(self, "错误", "数据库不存在\n请检查微信版本是否为最新")
self.DecryptSignal.emit(True)
self.close()
class DecryptThread(QThread):
signal = pyqtSignal(str)
maxNumSignal = pyqtSignal(int)
okSignal = pyqtSignal(str)
errorSignal = pyqtSignal(bool)
def __init__(self, db_path, key):
super(DecryptThread, self).__init__()
self.db_path = db_path
self.key = key
self.textBrowser = None
def __del__(self):
pass
def run(self):
misc_db.close()
msg_db.close()
# micro_msg_db.close()
# hard_link_db.close()
output_dir = 'app/DataBase/Msg'
os.makedirs(output_dir, exist_ok=True)
tasks = []
if os.path.exists(self.db_path):
for root, dirs, files in os.walk(self.db_path):
for file in files:
if '.db' == file[-3:]:
if 'xInfo.db' == file:
continue
inpath = os.path.join(root, file)
# print(inpath)
output_path = os.path.join(output_dir, file)
tasks.append([self.key, inpath, output_path])
self.maxNumSignal.emit(len(tasks))
for i, task in enumerate(tasks):
if decrypt.decrypt(*task) == -1:
self.errorSignal.emit(True)
self.signal.emit(str(i))
# print(self.db_path)
self.okSignal.emit('ok')
# self.signal.emit('100')
class MyThread(QThread):
signal = pyqtSignal(str)
def __init__(self):
super(MyThread, self).__init__()
def __del__(self):
pass
def run(self):
for i in range(100):
self.signal.emit(str(i))
time.sleep(0.1)

83
app/ui/tool/toolUI.py Normal file
View File

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'toolUI.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, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(590, 547)
font = QtGui.QFont()
font.setFamily("微软雅黑")
Dialog.setFont(font)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(Dialog)
self.label.setMaximumSize(QtCore.QSize(80, 80))
self.label.setText("")
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.listWidget = QtWidgets.QListWidget(Dialog)
self.listWidget.setMinimumSize(QtCore.QSize(100, 80))
self.listWidget.setMaximumSize(QtCore.QSize(500, 80))
self.listWidget.setFrameShape(QtWidgets.QFrame.NoFrame)
self.listWidget.setFrameShadow(QtWidgets.QFrame.Plain)
self.listWidget.setLineWidth(0)
self.listWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setFlow(QtWidgets.QListView.LeftToRight)
self.listWidget.setObjectName("listWidget")
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
self.horizontalLayout.addWidget(self.listWidget)
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setMaximumSize(QtCore.QSize(80, 80))
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.verticalLayout.addLayout(self.horizontalLayout)
self.stackedWidget = QtWidgets.QStackedWidget(Dialog)
self.stackedWidget.setObjectName("stackedWidget")
self.verticalLayout.addWidget(self.stackedWidget)
self.verticalLayout.setStretch(1, 1)
self.retranslateUi(Dialog)
self.stackedWidget.setCurrentIndex(-1)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
__sortingEnabled = self.listWidget.isSortingEnabled()
self.listWidget.setSortingEnabled(False)
item = self.listWidget.item(0)
item.setText(_translate("Dialog", "新建项目"))
item = self.listWidget.item(1)
item.setText(_translate("Dialog", "新建项目"))
item = self.listWidget.item(2)
item.setText(_translate("Dialog", "新建项目"))
item = self.listWidget.item(3)
item.setText(_translate("Dialog", "新建项目"))
item = self.listWidget.item(4)
item.setText(_translate("Dialog", "新建项目"))
self.listWidget.setSortingEnabled(__sortingEnabled)

View File

@ -0,0 +1,89 @@
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel
from app.ui.Icon import Icon
from .pc_decrypt import DecryptControl
from .toolUI import Ui_Dialog
# 美化样式表
Stylesheet = """
QPushButton{
background-color: #ffffff;
}
QPushButton:hover {
background-color: lightgray;
}
/*去掉item虚线边框*/
QListWidget, QListView, QTreeWidget, QTreeView {
outline: 0px;
border:none;
background-color:rgb(240,240,240)
}
/*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/
QListWidget {
min-width: 400px;
max-width: 400px;
min-height: 80px;
max-height: 80px;
color: black;
border:none;
}
QListWidget::item{
height:80px;
width:80px;
}
/*被选中时的背景颜色和左边框颜色*/
QListWidget::item:selected {
background: rgb(204, 204, 204);
border-bottom: 4px solid rgb(9, 187, 7);
border-left:none;
color: black;
font-weight: bold;
}
/*鼠标悬停颜色*/
HistoryPanel::item:hover {
background: rgb(52, 52, 52);
}
"""
class ToolWindow(QWidget, Ui_Dialog):
get_info_signal = pyqtSignal(str)
decrypt_success_signal = pyqtSignal(bool)
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()
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
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)
decrypt_window = DecryptControl()
decrypt_window.get_wxidSignal.connect(self.get_info_signal)
decrypt_window.DecryptSignal.connect(self.decrypt_success_signal)
self.stackedWidget.addWidget(decrypt_window)
label = QLabel('都说了不让你点', self)
label.setFont(QFont("微软雅黑", 50))
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(label)
self.stackedWidget.addWidget(label)
self.listWidget.setCurrentRow(0)
self.stackedWidget.setCurrentIndex(0)
def setCurrentIndex(self, row):
print(row)
self.stackedWidget.setCurrentIndex(row)

View File

@ -1,7 +1,7 @@
import os
import winreg
from app.person_pc import MePC
from app.person import MePC
from app.util import dat2pic
os.makedirs('./data/image', exist_ok=True)

View File

@ -3,10 +3,9 @@ import sys
from flask import Flask, render_template, send_file
from app.DataBase import msg_db
from app.analysis import analysis
from app.person_pc import ContactPC, MePC
from app.person import ContactPC, MePC
app = Flask(__name__)
@ -19,6 +18,7 @@ def index():
# 渲染模板,并传递图表的 HTML 到模板中
return render_template("index.html")
@app.route('/home')
def home():
try:
@ -39,12 +39,12 @@ def one(who):
wxid = contact.wxid
# wxid = 'wxid_lltzaezg38so22'
# print('wxid:'+wxid)
world_cloud_data = analysis.wordcloud(wxid,who=who) # 获取与Ta的对话数据
world_cloud_data = analysis.wordcloud(wxid, who=who) # 获取与Ta的对话数据
# print(world_cloud_data)
who = "" if who == '1' else "TA"
with open('wordcloud.html', 'w', encoding='utf-8') as f:
f.write(render_template('wordcloud.html', **world_cloud_data))
return render_template('wordcloud.html', **world_cloud_data,who=who)
return render_template('wordcloud.html', **world_cloud_data, who=who)
def set_text(text):