From 37870f1033859b70f03cd3befa5c3d1846d2e6d3 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 15 Nov 2023 20:54:27 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 71 +++- app/Ui/__init__.py | 3 +- app/Ui/chat/chat.py | 2 +- app/Ui/contact/contact.py | 2 +- app/Ui/mainview.py | 13 +- app/Ui/pc_decrypt/__init__.py | 0 app/Ui/pc_decrypt/decryptUi.py | 120 ------- app/Ui/pc_decrypt/decryptUi.ui | 221 ------------ .../Button_Contact.py | 0 .../MyComponents => components}/__init__.py | 0 .../MyComponents => components}/prompt_bar.py | 0 app/ui_pc/Icon.py | 18 + app/ui_pc/__init__.py | 3 + app/ui_pc/mainview.py | 117 +++++++ app/ui_pc/mainwindow.py | 149 ++++++++ app/ui_pc/mainwindow.ui | 242 +++++++++++++ app/ui_pc/tool/__init__.py | 3 + app/ui_pc/tool/pc_decrypt/__init__.py | 3 + app/ui_pc/tool/pc_decrypt/decryptUi.py | 164 +++++++++ app/ui_pc/tool/pc_decrypt/decryptUi.ui | 328 ++++++++++++++++++ .../tool}/pc_decrypt/pc_decrypt.py | 2 +- app/ui_pc/tool/toolUI.py | 83 +++++ app/ui_pc/tool/toolUI.ui | 128 +++++++ app/ui_pc/tool/tool_window.py | 77 ++++ decrypt_window.py | 24 +- main.py | 2 +- 26 files changed, 1403 insertions(+), 372 deletions(-) delete mode 100644 app/Ui/pc_decrypt/__init__.py delete mode 100644 app/Ui/pc_decrypt/decryptUi.py delete mode 100644 app/Ui/pc_decrypt/decryptUi.ui rename app/{Ui/MyComponents => components}/Button_Contact.py (100%) rename app/{Ui/MyComponents => components}/__init__.py (100%) rename app/{Ui/MyComponents => components}/prompt_bar.py (100%) create mode 100644 app/ui_pc/Icon.py create mode 100644 app/ui_pc/__init__.py create mode 100644 app/ui_pc/mainview.py create mode 100644 app/ui_pc/mainwindow.py create mode 100644 app/ui_pc/mainwindow.ui create mode 100644 app/ui_pc/tool/__init__.py create mode 100644 app/ui_pc/tool/pc_decrypt/__init__.py create mode 100644 app/ui_pc/tool/pc_decrypt/decryptUi.py create mode 100644 app/ui_pc/tool/pc_decrypt/decryptUi.ui rename app/{Ui => ui_pc/tool}/pc_decrypt/pc_decrypt.py (99%) create mode 100644 app/ui_pc/tool/toolUI.py create mode 100644 app/ui_pc/tool/toolUI.ui create mode 100644 app/ui_pc/tool/tool_window.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index bc75c5a..46102d6 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,10 +4,25 @@ - @@ -626,7 +670,8 @@ - diff --git a/app/Ui/__init__.py b/app/Ui/__init__.py index 380c558..730bbfa 100644 --- a/app/Ui/__init__.py +++ b/app/Ui/__init__.py @@ -13,6 +13,5 @@ from app.Ui import mainview # 文件__init__.py # from login import login from app.Ui.decrypt import decrypt -from app.Ui.pc_decrypt import pc_decrypt -__all__ = ["decrypt", 'mainview', 'chat', 'pc_decrypt'] +__all__ = ["decrypt", 'mainview', 'chat'] diff --git a/app/Ui/chat/chat.py b/app/Ui/chat/chat.py index 068a8ff..e913a63 100644 --- a/app/Ui/chat/chat.py +++ b/app/Ui/chat/chat.py @@ -17,7 +17,7 @@ from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * -from app.Ui.MyComponents.Button_Contact import ContactUi +from app.components.Button_Contact import ContactUi from app.log import logger, log from .chatUi import * from ...DataBase import data diff --git a/app/Ui/contact/contact.py b/app/Ui/contact/contact.py index 99556b7..aab92cb 100644 --- a/app/Ui/contact/contact.py +++ b/app/Ui/contact/contact.py @@ -13,7 +13,7 @@ from PyQt5 import QtCore from PyQt5.QtCore import * from PyQt5.QtWidgets import * -import app.Ui.MyComponents.Button_Contact as MyLabel +import app.components.Button_Contact as MyLabel from app import person from app.DataBase import data from app.Ui.contact.contactInfo import ContactInfo diff --git a/app/Ui/mainview.py b/app/Ui/mainview.py index ce69bf6..16ddfff 100644 --- a/app/Ui/mainview.py +++ b/app/Ui/mainview.py @@ -11,13 +11,12 @@ from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * -from app import person, config -from app.DataBase import * +from app import config from app.Ui import mainwindow from app.Ui.Icon import Icon -from app.Ui.MyComponents.prompt_bar import PromptBar from app.Ui.chat import chat from app.Ui.contact import contact +from app.components.prompt_bar import PromptBar class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): @@ -28,7 +27,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): super(MainWinController, self).__init__(parent) self.setupUi(self) self.setWindowIcon(Icon.MainWindow_Icon) - self.Me = person.Me(data.get_myinfo()) + self.setAttribute(Qt.WA_AttributeCount) self.chatView = chat.ChatController(self.Me, parent=None) @@ -60,12 +59,6 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.statusbar.setVisible(False) self.prompt_bar = PromptBar(self) self.chat_view() - # self.state_lable = QLabel(self) - # self.state_lable.raise_() - # pixmap = QPixmap('./app/data/icons/default_avatar.svg').scaled(32, 32) # 按指定路径找到图片 - # self.state_lable.setPixmap(pixmap) - # self.state_lable.setText("T") - # 创建右键菜单函数 def init_ui(self): # self.setWindowFlags(QtCore.Qt.FramelessWindowHint) diff --git a/app/Ui/pc_decrypt/__init__.py b/app/Ui/pc_decrypt/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/Ui/pc_decrypt/decryptUi.py b/app/Ui/pc_decrypt/decryptUi.py deleted file mode 100644 index 57a8b66..0000000 --- a/app/Ui/pc_decrypt/decryptUi.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- 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(400, 300) - font = QtGui.QFont() - font.setFamily("微软雅黑") - Dialog.setFont(font) - self.label_3 = QtWidgets.QLabel(Dialog) - self.label_3.setGeometry(QtCore.QRect(140, 0, 221, 51)) - font = QtGui.QFont() - font.setFamily("一纸情书") - font.setPointSize(20) - self.label_3.setFont(font) - self.label_3.setObjectName("label_3") - self.progressBar = QtWidgets.QProgressBar(Dialog) - self.progressBar.setGeometry(QtCore.QRect(90, 260, 271, 23)) - self.progressBar.setProperty("value", 50) - self.progressBar.setObjectName("progressBar") - self.btn_getinfo = QtWidgets.QPushButton(Dialog) - self.btn_getinfo.setGeometry(QtCore.QRect(290, 60, 91, 41)) - self.btn_getinfo.setObjectName("btn_getinfo") - self.btn_db_dir = QtWidgets.QPushButton(Dialog) - self.btn_db_dir.setGeometry(QtCore.QRect(20, 210, 91, 41)) - self.btn_db_dir.setObjectName("btn_db_dir") - self.label_db_dir = QtWidgets.QLabel(Dialog) - self.label_db_dir.setGeometry(QtCore.QRect(120, 220, 251, 21)) - self.label_db_dir.setText("") - self.label_db_dir.setObjectName("label_db_dir") - self.label_ready = QtWidgets.QLabel(Dialog) - self.label_ready.setGeometry(QtCore.QRect(40, 260, 41, 21)) - self.label_ready.setObjectName("label_ready") - self.layoutWidget = QtWidgets.QWidget(Dialog) - self.layoutWidget.setGeometry(QtCore.QRect(20, 50, 221, 151)) - self.layoutWidget.setObjectName("layoutWidget") - self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) - self.gridLayout.setContentsMargins(0, 0, 0, 0) - self.gridLayout.setObjectName("gridLayout") - self.label = QtWidgets.QLabel(self.layoutWidget) - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - self.label_2 = QtWidgets.QLabel(self.layoutWidget) - self.label_2.setObjectName("label_2") - self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1) - self.label_5 = QtWidgets.QLabel(self.layoutWidget) - self.label_5.setObjectName("label_5") - self.gridLayout.addWidget(self.label_5, 3, 0, 1, 1) - self.label_4 = QtWidgets.QLabel(self.layoutWidget) - self.label_4.setObjectName("label_4") - self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1) - self.label_key = QtWidgets.QLabel(self.layoutWidget) - self.label_key.setText("") - self.label_key.setObjectName("label_key") - self.gridLayout.addWidget(self.label_key, 5, 1, 1, 1) - self.label_phone = QtWidgets.QLabel(self.layoutWidget) - self.label_phone.setText("") - self.label_phone.setObjectName("label_phone") - self.gridLayout.addWidget(self.label_phone, 2, 1, 1, 1) - self.label_6 = QtWidgets.QLabel(self.layoutWidget) - self.label_6.setObjectName("label_6") - self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1) - self.label_pid = QtWidgets.QLabel(self.layoutWidget) - 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(self.layoutWidget) - self.label_name.setText("") - self.label_name.setObjectName("label_name") - self.gridLayout.addWidget(self.label_name, 3, 1, 1, 1) - self.label_7 = QtWidgets.QLabel(self.layoutWidget) - self.label_7.setObjectName("label_7") - self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1) - self.label_version = QtWidgets.QLabel(self.layoutWidget) - self.label_version.setText("") - self.label_version.setObjectName("label_version") - self.gridLayout.addWidget(self.label_version, 1, 1, 1, 1) - self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget) - self.lineEdit.setStyleSheet("background:transparent;border-width:0;border-style:outset") - self.lineEdit.setFrame(False) - self.lineEdit.setObjectName("lineEdit") - self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1) - self.gridLayout.setColumnMinimumWidth(0, 1) - self.gridLayout.setColumnMinimumWidth(1, 2) - self.gridLayout.setRowMinimumHeight(5, 10) - self.gridLayout.setColumnStretch(0, 1) - self.gridLayout.setColumnStretch(1, 3) - self.gridLayout.setRowStretch(5, 10) - self.pushButton_3 = QtWidgets.QPushButton(Dialog) - self.pushButton_3.setGeometry(QtCore.QRect(290, 130, 91, 41)) - self.pushButton_3.setObjectName("pushButton_3") - - self.retranslateUi(Dialog) - QtCore.QMetaObject.connectSlotsByName(Dialog) - - def retranslateUi(self, Dialog): - _translate = QtCore.QCoreApplication.translate - Dialog.setWindowTitle(_translate("Dialog", "Dialog")) - self.label_3.setText(_translate("Dialog", "解密数据库")) - self.btn_getinfo.setText(_translate("Dialog", "获取信息")) - self.btn_db_dir.setText(_translate("Dialog", "设置微信路径")) - self.label_ready.setText(_translate("Dialog", "未就绪")) - self.label.setText(_translate("Dialog", "PID")) - self.label_2.setText(_translate("Dialog", "手机号")) - self.label_5.setText(_translate("Dialog", "微信昵称")) - self.label_4.setText(_translate("Dialog", "wxid")) - self.label_6.setText(_translate("Dialog", "密钥")) - self.label_7.setText(_translate("Dialog", "版本")) - self.pushButton_3.setText(_translate("Dialog", "开始解密")) diff --git a/app/Ui/pc_decrypt/decryptUi.ui b/app/Ui/pc_decrypt/decryptUi.ui deleted file mode 100644 index fe1b558..0000000 --- a/app/Ui/pc_decrypt/decryptUi.ui +++ /dev/null @@ -1,221 +0,0 @@ - - - Dialog - - - - 0 - 0 - 400 - 300 - - - - - 微软雅黑 - - - - Dialog - - - - - 140 - 0 - 221 - 51 - - - - - 一纸情书 - 20 - - - - 解密数据库 - - - - - - 90 - 260 - 271 - 23 - - - - 50 - - - - - - 290 - 60 - 91 - 41 - - - - 获取信息 - - - - - - 20 - 210 - 91 - 41 - - - - 设置微信路径 - - - - - - 120 - 220 - 251 - 21 - - - - - - - - - - 40 - 260 - 41 - 21 - - - - 未就绪 - - - - - - 20 - 50 - 221 - 151 - - - - - - - PID - - - - - - - 手机号 - - - - - - - 微信昵称 - - - - - - - wxid - - - - - - - - - - - - - - - - - - - - - 密钥 - - - - - - - - - - - - - - - - - - - - - 版本 - - - - - - - - - - - - - - background:transparent;border-width:0;border-style:outset - - - false - - - - - - - - - 290 - 130 - 91 - 41 - - - - 开始解密 - - - - - - diff --git a/app/Ui/MyComponents/Button_Contact.py b/app/components/Button_Contact.py similarity index 100% rename from app/Ui/MyComponents/Button_Contact.py rename to app/components/Button_Contact.py diff --git a/app/Ui/MyComponents/__init__.py b/app/components/__init__.py similarity index 100% rename from app/Ui/MyComponents/__init__.py rename to app/components/__init__.py diff --git a/app/Ui/MyComponents/prompt_bar.py b/app/components/prompt_bar.py similarity index 100% rename from app/Ui/MyComponents/prompt_bar.py rename to app/components/prompt_bar.py diff --git a/app/ui_pc/Icon.py b/app/ui_pc/Icon.py new file mode 100644 index 0000000..808fae3 --- /dev/null +++ b/app/ui_pc/Icon.py @@ -0,0 +1,18 @@ +from PyQt5.QtGui import QIcon + + +class Icon: + Default_avatar_path = './app/data/icons/default_avatar.svg' + MainWindow_Icon = QIcon('./app/data/icons/logo.svg') + Default_avatar = QIcon(Default_avatar_path) + Output = QIcon('./app/data/icons/output.svg') + Back = QIcon('./app/data/icons/back.svg') + ToDocx = QIcon('app/data/icons/word.svg') + ToCSV = QIcon('app/data/icons/csv.svg') + ToHTML = QIcon('app/data/icons/html.svg') + Chat_Icon = QIcon('./app/data/icons/chat.svg') + Contact_Icon = QIcon('./app/data/icons/contact.svg') + MyInfo_Icon = QIcon('./app/data/icons/myinfo.svg') + Annual_Report_Icon = QIcon('./app/data/icons/annual_report.svg') + Analysis_Icon = QIcon('./app/data/icons/analysis.svg') + Emotion_Icon = QIcon('./app/data/icons/emotion.svg') diff --git a/app/ui_pc/__init__.py b/app/ui_pc/__init__.py new file mode 100644 index 0000000..5cbf985 --- /dev/null +++ b/app/ui_pc/__init__.py @@ -0,0 +1,3 @@ +from . import mainview + +__all__ = ['mainview'] diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py new file mode 100644 index 0000000..010c90e --- /dev/null +++ b/app/ui_pc/mainview.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +""" +@File : mainview.py +@Author : Shuaikang Zhou +@Time : 2022/12/13 15:07 +@IDE : Pycharm +@Version : Python3.10 +@comment : 主窗口 +""" +from random import randint + +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * + +from app import config +from app.Ui.Icon import Icon +from . import mainwindow +from .tool import ToolWindow + +# 美化样式表 +Stylesheet = """ +QPushButton { + background-color: rgb(240,240,240); + border:none; +} +QPushButton:hover{ + background-color: rgb(209,209,209); +} +/*去掉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() + + # username = '' + def __init__(self, username, parent=None): + super(MainWinController, self).__init__(parent) + self.setupUi(self) + self.setWindowIcon(Icon.MainWindow_Icon) + self.setStyleSheet(Stylesheet) + self.listWidget.clear() + # self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget) + self.action_desc.triggered.connect(self.about) + self.init_ui() + + def init_ui(self): + 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) + 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) + 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) + 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) + self.stackedWidget.addWidget(tool_window) + self.listWidget.setCurrentRow(3) + self.stackedWidget.setCurrentIndex(3) + + def setCurrentIndex(self, row): + print(row) + self.stackedWidget.setCurrentIndex(row) + + def about(self): + """ + 关于 + """ + QMessageBox.about(self, "关于", + f"版本:{config.version}\n" + f"QQ交流群:{config.contact}\n" + "地址:https://github.com/LC044/WeChatMsg" + ) diff --git a/app/ui_pc/mainwindow.py b/app/ui_pc/mainwindow.py new file mode 100644 index 0000000..9347ae1 --- /dev/null +++ b/app/ui_pc/mainwindow.py @@ -0,0 +1,149 @@ +# -*- 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" + "}") + 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.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 = QtWidgets.QMenu(self.menubar) + font = QtGui.QFont() + font.setFamily("微软雅黑") + self.menu.setFont(font) + self.menu.setObjectName("menu") + 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") + 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 = QtWidgets.QAction(MainWindow) + font = QtGui.QFont() + font.setFamily("Microsoft YaHei UI") + self.action.setFont(font) + self.action.setObjectName("action") + self.action_desc = QtWidgets.QAction(MainWindow) + self.action_desc.setObjectName("action_desc") + self.menu_F.addSeparator() + self.menu_F.addSeparator() + self.menu_F.addAction(self.action_3) + self.menu_F.addAction(self.action_4) + self.menu_2.addAction(self.action) + self.menu_about.addAction(self.action_desc) + self.menubar.addAction(self.menu_F.menuAction()) + self.menubar.addAction(self.menu.menuAction()) + self.menubar.addAction(self.menu_2.menuAction()) + self.menubar.addAction(self.menu_about.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.setTitle(_translate("MainWindow", "编辑")) + self.menu_2.setTitle(_translate("MainWindow", "帮助")) + self.menu_about.setTitle(_translate("MainWindow", "关于")) + self.action_3.setText(_translate("MainWindow", "保存")) + self.action_4.setText(_translate("MainWindow", "退出")) + self.action.setText(_translate("MainWindow", "关于")) + self.action_desc.setText(_translate("MainWindow", "说明")) diff --git a/app/ui_pc/mainwindow.ui b/app/ui_pc/mainwindow.ui new file mode 100644 index 0000000..3bbcb76 --- /dev/null +++ b/app/ui_pc/mainwindow.ui @@ -0,0 +1,242 @@ + + + MainWindow + + + + 0 + 0 + 1280 + 779 + + + + MainWindow + + + + /*去掉item虚线边框*/ + QListWidget, QListView, QTreeWidget, QTreeView { + outline: 0px; + } + /*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/ + QListWidget { + min-width: 120px; + max-width: 120px; + color: black; + background: white; + border:none; + } + QListWidget::item{ + height:80; + } + /*被选中时的背景颜色和左边框颜色*/ + QListWidget::item:selected { + background: rgb(204, 204, 204); + border-left: 4px solid rgb(9, 187, 7); + } + /*鼠标悬停颜色*/ + HistoryPanel::item:hover { + background: rgb(52, 52, 52); + } + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 80 + 500 + + + + + 80 + 16777215 + + + + background-color:rgb(240,240,240) + + + QFrame::NoFrame + + + QFrame::Plain + + + + + 10 + 40 + 60 + 60 + + + + avatar + + + + + + 0 + 230 + 80 + 331 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustIgnored + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + + + + + + 微软雅黑 + 50 + false + + + + + + + + + + 0 + 0 + 1280 + 23 + + + + + 文件(F) + + + + + + + + + + 微软雅黑 + + + + 编辑 + + + + + 帮助 + + + + + + 关于 + + + + + + + + + + + + 保存 + + + + + 退出 + + + + + 关于 + + + + Microsoft YaHei UI + + + + + + 说明 + + + + + + diff --git a/app/ui_pc/tool/__init__.py b/app/ui_pc/tool/__init__.py new file mode 100644 index 0000000..8fe2f8e --- /dev/null +++ b/app/ui_pc/tool/__init__.py @@ -0,0 +1,3 @@ +from .tool_window import ToolWindow + +__all__ = ['ToolWindow'] diff --git a/app/ui_pc/tool/pc_decrypt/__init__.py b/app/ui_pc/tool/pc_decrypt/__init__.py new file mode 100644 index 0000000..ae1c618 --- /dev/null +++ b/app/ui_pc/tool/pc_decrypt/__init__.py @@ -0,0 +1,3 @@ +from .pc_decrypt import DecryptControl + +__all__ = ['DecryptControl'] diff --git a/app/ui_pc/tool/pc_decrypt/decryptUi.py b/app/ui_pc/tool/pc_decrypt/decryptUi.py new file mode 100644 index 0000000..44145d5 --- /dev/null +++ b/app/ui_pc/tool/pc_decrypt/decryptUi.py @@ -0,0 +1,164 @@ +# -*- 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.horizontalLayout_4 = QtWidgets.QHBoxLayout(Dialog) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem1) + 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.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;border-width:0;border-style:outset") + 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.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.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") + spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem2) + 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) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem3) + 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) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem4) + self.verticalLayout_2.addLayout(self.horizontalLayout_3) + spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem5) + self.horizontalLayout_4.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.label_3.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_ready.setText(_translate("Dialog", "未就绪")) diff --git a/app/ui_pc/tool/pc_decrypt/decryptUi.ui b/app/ui_pc/tool/pc_decrypt/decryptUi.ui new file mode 100644 index 0000000..846fc4c --- /dev/null +++ b/app/ui_pc/tool/pc_decrypt/decryptUi.ui @@ -0,0 +1,328 @@ + + + Dialog + + + + 0 + 0 + 611 + 519 + + + + + 微软雅黑 + + + + Dialog + + + Qt::LeftToRight + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 一纸情书 + 20 + + + + 解密数据库 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + 版本 + + + + + + + + background:transparent;border-width:0;border-style:outset + + + + false + + + + + + + 微信昵称 + + + + + + + 密钥 + + + + + + + + + + + + + + PID + + + + + + + 手机号 + + + + + + + + + + + + + + + + + + + + + wxid + + + + + + + + + + + + + + 微信路径 + + + + + + + + + + + + + + + + + 0 + 60 + + + + 获取信息 + + + + + + + + + + + + + + + 0 + 60 + + + + 设置微信路径 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 60 + + + + + 100 + 16777215 + + + + 开始解密 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 未就绪 + + + + + + + 50 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/app/Ui/pc_decrypt/pc_decrypt.py b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py similarity index 99% rename from app/Ui/pc_decrypt/pc_decrypt.py rename to app/ui_pc/tool/pc_decrypt/pc_decrypt.py index 9f236f2..af71116 100644 --- a/app/Ui/pc_decrypt/pc_decrypt.py +++ b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py @@ -88,7 +88,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): # 中间可以添加处理逻辑 # QMessageBox.about(self, "解密成功", "数据库文件存储在app/DataBase/Msg文件夹下") self.DecryptSignal.emit('ok') - self.close() + # self.close() def setProgressBarMaxNum(self, max_val): self.progressBar.setRange(0, max_val) diff --git a/app/ui_pc/tool/toolUI.py b/app/ui_pc/tool/toolUI.py new file mode 100644 index 0000000..c459a95 --- /dev/null +++ b/app/ui_pc/tool/toolUI.py @@ -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(630, 633) + 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.setObjectName("label") + self.horizontalLayout.addWidget(self.label) + self.listWidget = QtWidgets.QListWidget(Dialog) + self.listWidget.setMinimumSize(QtCore.QSize(500, 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.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")) + self.label.setText(_translate("Dialog", "TextLabel")) + __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) + self.label_2.setText(_translate("Dialog", "TextLabel")) diff --git a/app/ui_pc/tool/toolUI.ui b/app/ui_pc/tool/toolUI.ui new file mode 100644 index 0000000..19fb825 --- /dev/null +++ b/app/ui_pc/tool/toolUI.ui @@ -0,0 +1,128 @@ + + + Dialog + + + + 0 + 0 + 630 + 547 + + + + + 微软雅黑 + + + + Dialog + + + + + + 0 + + + QLayout::SetDefaultConstraint + + + + + + 80 + 80 + + + + TextLabel + + + + + + + + 500 + 80 + + + + + 500 + 80 + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QListView::LeftToRight + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + + + + + 80 + 80 + + + + TextLabel + + + + + + + + + -1 + + + + + + + + diff --git a/app/ui_pc/tool/tool_window.py b/app/ui_pc/tool/tool_window.py new file mode 100644 index 0000000..29d1bf3 --- /dev/null +++ b/app/ui_pc/tool/tool_window.py @@ -0,0 +1,77 @@ +from random import randint + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel + +from .pc_decrypt import DecryptControl +from .toolUI import Ui_Dialog +from ...Ui.Icon import Icon + +# 美化样式表 +Stylesheet = """ + +/*去掉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): + def __init__(self, parent=None): + super().__init__(parent) + self.setupUi(self) + self.setStyleSheet(Stylesheet) + self.init_ui() + + 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, '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) + 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) + 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) diff --git a/decrypt_window.py b/decrypt_window.py index 2918b42..04f7b7b 100644 --- a/decrypt_window.py +++ b/decrypt_window.py @@ -1,10 +1,12 @@ import ctypes import sys +import time from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import * -from app.Ui import pc_decrypt +from app.ui_pc import mainview +from app.ui_pc.tool.pc_decrypt import pc_decrypt ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport") @@ -26,6 +28,23 @@ 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文件夹下") @@ -33,6 +52,7 @@ class ViewController(QWidget): if __name__ == '__main__': app = QApplication(sys.argv) view = ViewController() - view.loadPCDecryptView() + # view.loadPCDecryptView() + view.loadMainWinView() # view.show_success() sys.exit(app.exec_()) diff --git a/main.py b/main.py index 6fdd1dd..b21f867 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,7 @@ import time from PyQt5.QtWidgets import * import app.DataBase.data as DB -from app.Ui import decrypt, mainview, pc_decrypt +from app.Ui import decrypt, mainview ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport") From 07b20a2f210a46e6ba9113e18a43222810cd680c Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 15 Nov 2023 21:57:29 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=81=94=E7=B3=BB?= =?UTF-8?q?=E4=BA=BA=E5=A4=B4=E5=83=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 144 +++++++------- app/DataBase/micro_msg.py | 20 +- app/components/CAvatar.py | 283 ++++++++++++++++++++++++++++ app/components/__init__.py | 1 + app/components/contact_info_ui.py | 57 ++++++ app/person.py | 13 ++ app/ui_pc/contact/__init__.py | 1 + app/ui_pc/contact/contactUi.py | 53 ++++++ app/ui_pc/contact/contactUi.ui | 84 +++++++++ app/ui_pc/contact/contact_window.py | 99 ++++++++++ app/ui_pc/mainview.py | 12 +- 11 files changed, 677 insertions(+), 90 deletions(-) create mode 100644 app/components/CAvatar.py create mode 100644 app/components/contact_info_ui.py create mode 100644 app/ui_pc/contact/__init__.py create mode 100644 app/ui_pc/contact/contactUi.py create mode 100644 app/ui_pc/contact/contactUi.ui create mode 100644 app/ui_pc/contact/contact_window.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 46102d6..c810fe6 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,25 +4,17 @@ - @@ -671,7 +662,8 @@ - diff --git a/app/DataBase/micro_msg.py b/app/DataBase/micro_msg.py index 972a258..9a99a2c 100644 --- a/app/DataBase/micro_msg.py +++ b/app/DataBase/micro_msg.py @@ -1,9 +1,17 @@ +import os.path import sqlite3 -from pprint import pprint -DB = sqlite3.connect("./de_MicroMsg.db", check_same_thread=False) -# '''创建游标''' -cursor = DB.cursor() +DB = None +cursor = None +micromsg_path = "./app/Database/Msg/MicroMsg.db" +if os.path.exists(micromsg_path): + DB = sqlite3.connect(micromsg_path, check_same_thread=False) + # '''创建游标''' + cursor = DB.cursor() + + +def is_database_exist(): + return os.path.exists(micromsg_path) def get_contact(): @@ -14,8 +22,8 @@ def get_contact(): ''' cursor.execute(sql) result = cursor.fetchall() - pprint(result) - print(len(result)) + # pprint(result) + # print(len(result)) return result diff --git a/app/components/CAvatar.py b/app/components/CAvatar.py new file mode 100644 index 0000000..09dbb09 --- /dev/null +++ b/app/components/CAvatar.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2019年7月26日 +@author: Irony +@site: https://pyqt5.com https://github.com/892768447 +@email: 892768447@qq.com +@file: CustomWidgets.CAvatar +@description: 头像 +""" +import os + +from PyQt5.QtCore import QUrl, QRectF, Qt, QSize, QTimer, QPropertyAnimation, \ + QPointF, pyqtProperty +from PyQt5.QtGui import QPixmap, QColor, QPainter, QPainterPath, QMovie +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkDiskCache, \ + QNetworkRequest +from PyQt5.QtWidgets import QWidget, qApp + +__Author__ = 'Irony' +__Copyright__ = 'Copyright (c) 2019 Irony' +__Version__ = 1.0 + + +class CAvatar(QWidget): + Circle = 0 # 圆圈 + Rectangle = 1 # 圆角矩形 + SizeLarge = QSize(128, 128) + SizeMedium = QSize(64, 64) + SizeSmall = QSize(32, 32) + StartAngle = 0 # 起始旋转角度 + EndAngle = 360 # 结束旋转角度 + + def __init__(self, *args, shape=0, url='', cacheDir=False, size=QSize(64, 64), animation=False, **kwargs): + super(CAvatar, self).__init__(*args, **kwargs) + self.url = '' + self._angle = 0 # 角度 + self.pradius = 0 # 加载进度条半径 + self.animation = animation # 是否使用动画 + self._movie = None # 动态图 + self._pixmap = QPixmap() # 图片对象 + self.pixmap = QPixmap() # 被绘制的对象 + self.isGif = url.endswith('.gif') + # 进度动画定时器 + self.loadingTimer = QTimer(self, timeout=self.onLoading) + # 旋转动画 + self.rotateAnimation = QPropertyAnimation( + self, b'angle', self, loopCount=1) + self.setShape(shape) + self.setCacheDir(cacheDir) + self.setSize(size) + self.setUrl(url) + + def paintEvent(self, event): + super(CAvatar, self).paintEvent(event) + # 画笔 + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing, True) + painter.setRenderHint(QPainter.HighQualityAntialiasing, True) + painter.setRenderHint(QPainter.SmoothPixmapTransform, True) + # 绘制 + path = QPainterPath() + diameter = min(self.width(), self.height()) + if self.shape == self.Circle: + radius = int(diameter / 2) + elif self.shape == self.Rectangle: + radius = 4 + halfW = self.width() / 2 + halfH = self.height() / 2 + painter.translate(halfW, halfH) + path.addRoundedRect( + QRectF(-halfW, -halfH, diameter, diameter), radius, radius) + painter.setClipPath(path) + # 如果是动画效果 + if self.rotateAnimation.state() == QPropertyAnimation.Running: + painter.rotate(self._angle) # 旋转 + painter.drawPixmap( + QPointF(-self.pixmap.width() / 2, -self.pixmap.height() // 2), self.pixmap) + else: + painter.drawPixmap(-int(halfW), -int(halfH), self.pixmap) + # 如果在加载 + if self.loadingTimer.isActive(): + diameter = 2 * self.pradius + painter.setBrush( + QColor(45, 140, 240, int((1 - self.pradius / 10) * 255))) + painter.setPen(Qt.NoPen) + painter.drawRoundedRect( + QRectF(-self.pradius, -self.pradius, diameter, diameter), self.pradius, self.pradius) + + def enterEvent(self, event): + """鼠标进入动画 + :param event: + """ + if not (self.animation and not self.isGif): + return + self.rotateAnimation.stop() + cv = self.rotateAnimation.currentValue() or self.StartAngle + self.rotateAnimation.setDuration( + 540 if cv == 0 else int(cv / self.EndAngle * 540)) + self.rotateAnimation.setStartValue(cv) + self.rotateAnimation.setEndValue(self.EndAngle) + self.rotateAnimation.start() + + def leaveEvent(self, event): + """鼠标离开动画 + :param event: + """ + if not (self.animation and not self.isGif): + return + self.rotateAnimation.stop() + cv = self.rotateAnimation.currentValue() or self.EndAngle + self.rotateAnimation.setDuration(int(cv / self.EndAngle * 540)) + self.rotateAnimation.setStartValue(cv) + self.rotateAnimation.setEndValue(self.StartAngle) + self.rotateAnimation.start() + + def onLoading(self): + """更新进度动画 + """ + if self.loadingTimer.isActive(): + if self.pradius > 9: + self.pradius = 0 + self.pradius += 1 + else: + self.pradius = 0 + self.update() + + def onFinished(self): + """图片下载完成 + """ + self.loadingTimer.stop() + self.pradius = 0 + reply = self.sender() + + if self.isGif: + self._movie = QMovie(reply, b'gif', self) + if self._movie.isValid(): + self._movie.frameChanged.connect(self._resizeGifPixmap) + self._movie.start() + else: + data = reply.readAll().data() + reply.deleteLater() + del reply + self._pixmap.loadFromData(data) + if self._pixmap.isNull(): + self._pixmap = QPixmap(self.size()) + self._pixmap.fill(QColor(204, 204, 204)) + self._resizePixmap() + + def onError(self, code): + """下载出错了 + :param code: + """ + self._pixmap = QPixmap(self.size()) + self._pixmap.fill(QColor(204, 204, 204)) + self._resizePixmap() + + def refresh(self): + """强制刷新 + """ + self._get(self.url) + + def isLoading(self): + """判断是否正在加载 + """ + return self.loadingTimer.isActive() + + def setShape(self, shape): + """设置形状 + :param shape: 0=圆形, 1=圆角矩形 + """ + self.shape = shape + + def setUrl(self, url): + """设置url,可以是本地路径,也可以是网络地址 + :param url: + """ + self.url = url + self._get(url) + + def setCacheDir(self, cacheDir=''): + """设置本地缓存路径 + :param cacheDir: + """ + self.cacheDir = cacheDir + self._initNetWork() + + def setSize(self, size): + """设置固定尺寸 + :param size: + """ + if not isinstance(size, QSize): + size = self.SizeMedium + self.setMinimumSize(size) + self.setMaximumSize(size) + self._resizePixmap() + + @pyqtProperty(int) + def angle(self): + return self._angle + + @angle.setter + def angle(self, value): + self._angle = value + self.update() + + def _resizePixmap(self): + """缩放图片 + """ + if not self._pixmap.isNull(): + self.pixmap = self._pixmap.scaled( + self.width(), self.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) + self.update() + + def _resizeGifPixmap(self, _): + """缩放动画图片 + """ + if self._movie: + self.pixmap = self._movie.currentPixmap().scaled( + self.width(), self.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) + self.update() + + def _initNetWork(self): + """初始化异步网络库 + """ + if not hasattr(qApp, '_network'): + network = QNetworkAccessManager(self.window()) + setattr(qApp, '_network', network) + # 是否需要设置缓存 + if self.cacheDir and not qApp._network.cache(): + cache = QNetworkDiskCache(self.window()) + cache.setCacheDirectory(self.cacheDir) + qApp._network.setCache(cache) + + def _get(self, url): + """设置图片或者请求网络图片 + :param url: + """ + if not url: + self.onError('') + return + if url.startswith('http') and not self.loadingTimer.isActive(): + url = QUrl(url) + request = QNetworkRequest(url) + # request.setHeader(QNetworkRequest.UserAgentHeader, b'CAvatar') + # request.setRawHeader(b'Author', b'Irony') + request.setAttribute( + QNetworkRequest.FollowRedirectsAttribute, True) + if qApp._network.cache(): + request.setAttribute( + QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.PreferNetwork) + request.setAttribute( + QNetworkRequest.CacheSaveControlAttribute, True) + reply = qApp._network.get(request) + self.pradius = 0 + self.loadingTimer.start(50) # 显示进度动画 + reply.finished.connect(self.onFinished) + reply.error.connect(self.onError) + return + self.pradius = 0 + if os.path.exists(url) and os.path.isfile(url): + if self.isGif: + self._movie = QMovie(url, parent=self) + if self._movie.isValid(): + self._movie.frameChanged.connect(self._resizeGifPixmap) + self._movie.start() + else: + self._pixmap = QPixmap(url) + self._resizePixmap() + else: + self.onError('') + + +if __name__ == '__main__': + import sys + from PyQt5.QtWidgets import QApplication + + app = QApplication(sys.argv) + w = CAvatar( + url='https://wx.qlogo.cn/mmhead/ver_1/DpDqmvTDORNWfLrMj26YicorEUREffl1G8FapawdKgINVH9g1icudfWesGrH9LqeGAz16z4PmkW9U1KAIM3btWgozZ1GaLF66bdKdxlMdazmibn2hpFeiaa4613dN6HM4Vfk/132') + w.show() + sys.exit(app.exec_()) diff --git a/app/components/__init__.py b/app/components/__init__.py index e69de29..00aed52 100644 --- a/app/components/__init__.py +++ b/app/components/__init__.py @@ -0,0 +1 @@ +from .contact_info_ui import ContactQListWidgetItem diff --git a/app/components/contact_info_ui.py b/app/components/contact_info_ui.py new file mode 100644 index 0000000..d1a0411 --- /dev/null +++ b/app/components/contact_info_ui.py @@ -0,0 +1,57 @@ +import sys + +from PyQt5.Qt import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * + +from .CAvatar import CAvatar + + +# 自定义的item 继承自QListWidgetItem +class ContactQListWidgetItem(QListWidgetItem): + def __init__(self, name, url): + super().__init__() + # 自定义item中的widget 用来显示自定义的内容 + self.widget = QWidget() + # 用来显示name + self.nameLabel = QLabel() + self.nameLabel.setText(name) + # 用来显示avator(图像) + self.avatorLabel = CAvatar(None, shape=CAvatar.Rectangle, size=QSize(60, 60), + url=url) + # 设置布局用来对nameLabel和avatorLabel进行布局 + self.hbox = QHBoxLayout() + self.hbox.addWidget(self.avatorLabel) + self.hbox.addWidget(self.nameLabel) + self.hbox.addStretch(1) + # 设置widget的布局 + self.widget.setLayout(self.hbox) + # 设置自定义的QListWidgetItem的sizeHint,不然无法显示 + self.setSizeHint(self.widget.sizeHint()) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + # 主窗口 + w = QWidget() + w.setWindowTitle("QListWindow") + # 新建QListWidget + listWidget = QListWidget(w) + listWidget.resize(300, 300) + + # 新建两个自定义的QListWidgetItem(customQListWidgetItem) + item1 = ContactQListWidgetItem("鲤鱼王", "liyuwang.jpg") + item2 = ContactQListWidgetItem("可达鸭", "kedaya.jpg") + + # 在listWidget中加入两个自定义的item + listWidget.addItem(item1) + listWidget.setItemWidget(item1, item1.widget) + listWidget.addItem(item2) + listWidget.setItemWidget(item2, item2.widget) + + # 绑定点击槽函数 点击显示对应item中的name + listWidget.itemClicked.connect(lambda item: print(item.nameLabel.text())) + + w.show() + sys.exit(app.exec_()) diff --git a/app/person.py b/app/person.py index 68f8e5c..07f0d91 100644 --- a/app/person.py +++ b/app/person.py @@ -1,4 +1,5 @@ import os.path +from typing import Dict from PyQt5.QtGui import QPixmap @@ -32,6 +33,18 @@ class Me(Person): class Contact(Person): def __init__(self, wxid: str): super(Contact, self).__init__(wxid) + self.smallHeadImgUrl = '' + self.bigHeadImgUrl = '' + + +class ContactPC: + def __init__(self, contact_info: Dict): + self.wxid = contact_info.get('UserName') + self.remark = contact_info.get('Remark') + # Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl,bigHeadImgUrl + self.alias = contact_info.get('Alias') + self.nickName = contact_info.get('NickName') + self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl') class Group(Person): diff --git a/app/ui_pc/contact/__init__.py b/app/ui_pc/contact/__init__.py new file mode 100644 index 0000000..a83ae0a --- /dev/null +++ b/app/ui_pc/contact/__init__.py @@ -0,0 +1 @@ +from .contact_window import ContactWindow diff --git a/app/ui_pc/contact/contactUi.py b/app/ui_pc/contact/contactUi.py new file mode 100644 index 0000000..2fb6c1d --- /dev/null +++ b/app/ui_pc/contact/contactUi.py @@ -0,0 +1,53 @@ +# -*- 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 = QtWidgets.QHBoxLayout(Form) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.lineEdit = QtWidgets.QLineEdit(Form) + self.lineEdit.setMinimumSize(QtCore.QSize(250, 30)) + self.lineEdit.setMaximumSize(QtCore.QSize(250, 16777215)) + self.lineEdit.setObjectName("lineEdit") + self.verticalLayout.addWidget(self.lineEdit) + 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.addWidget(self.listWidget) + self.horizontalLayout.addLayout(self.verticalLayout) + self.stackedWidget = QtWidgets.QStackedWidget(Form) + self.stackedWidget.setObjectName("stackedWidget") + self.page = QtWidgets.QWidget() + self.page.setObjectName("page") + self.stackedWidget.addWidget(self.page) + self.page_2 = QtWidgets.QWidget() + self.page_2.setObjectName("page_2") + self.stackedWidget.addWidget(self.page_2) + self.horizontalLayout.addWidget(self.stackedWidget) + self.horizontalLayout.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/contact/contactUi.ui b/app/ui_pc/contact/contactUi.ui new file mode 100644 index 0000000..4a432b1 --- /dev/null +++ b/app/ui_pc/contact/contactUi.ui @@ -0,0 +1,84 @@ + + + Form + + + + 0 + 0 + 840 + 752 + + + + Form + + + background: rgb(240, 240, 240); + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 250 + 30 + + + + + 250 + 16777215 + + + + + + + + + 250 + 0 + + + + + 250 + 16777215 + + + + Qt::ScrollBarAlwaysOff + + + + + + + + + 1 + + + + + + + + + + diff --git a/app/ui_pc/contact/contact_window.py b/app/ui_pc/contact/contact_window.py new file mode 100644 index 0000000..00050cd --- /dev/null +++ b/app/ui_pc/contact/contact_window.py @@ -0,0 +1,99 @@ +from random import randint + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel, QMessageBox + +from app.DataBase import micro_msg +from app.components import ContactQListWidgetItem +from app.person import ContactPC +from .contactUi import Ui_Form +from ...Ui.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 ContactWindow(QWidget, Ui_Form): + def __init__(self, parent=None): + super().__init__(parent) + self.setupUi(self) + self.setStyleSheet(Stylesheet) + self.init_ui() + self.show_contacts() + + 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, 'None', self.listWidget) + myinfo_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget) + tool_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget) + 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) + self.stackedWidget.addWidget(label) + self.stackedWidget.addWidget(label) + self.listWidget.setCurrentRow(0) + self.stackedWidget.setCurrentIndex(0) + + def show_contacts(self): + if not micro_msg.is_database_exist(): + QMessageBox.critical(self, "错误", "数据库不存在\n请先解密数据库") + return + 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) + # pprint(contact.__dict__) + contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl) + self.listWidget.addItem(contact_item) + self.listWidget.setItemWidget(contact_item, contact_item.widget) + + def setCurrentIndex(self, row): + print(row) + self.stackedWidget.setCurrentIndex(row) diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py index 010c90e..5d73691 100644 --- a/app/ui_pc/mainview.py +++ b/app/ui_pc/mainview.py @@ -15,6 +15,7 @@ from PyQt5.QtWidgets import * from app import config from app.Ui.Icon import Icon from . import mainwindow +from .contact import ContactWindow from .tool import ToolWindow # 美化样式表 @@ -75,22 +76,17 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): contact_item = QListWidgetItem(Icon.Contact_Icon, '好友', self.listWidget) myinfo_item = QListWidgetItem(Icon.MyInfo_Icon, '我的', self.listWidget) tool_item = QListWidgetItem(Icon.MyInfo_Icon, '工具', self.listWidget) + tool_window = ToolWindow() 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) - 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) + contact_window = ContactWindow() + self.stackedWidget.addWidget(contact_window) label = QLabel('我是页面', self) label.setAlignment(Qt.AlignCenter) # 设置label的背景颜色(这里随机) From 286e2d627c04978d351e327b9050456f5ef619f7 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 15 Nov 2023 22:32:11 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=A4=B4=E5=83=8F=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E4=BA=8C=E8=BF=9B=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 46 +++++++++++++---------------- app/DataBase/misc.py | 29 ++++++++++++++++++ app/components/CAvatar.py | 18 +++++++++-- app/components/contact_info_ui.py | 4 +-- app/person.py | 1 + app/ui_pc/contact/contact_window.py | 24 +++------------ 6 files changed, 73 insertions(+), 49 deletions(-) create mode 100644 app/DataBase/misc.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c810fe6..5f03fbf 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,17 +4,13 @@ - @@ -663,7 +658,8 @@ - diff --git a/app/DataBase/misc.py b/app/DataBase/misc.py new file mode 100644 index 0000000..357d6ce --- /dev/null +++ b/app/DataBase/misc.py @@ -0,0 +1,29 @@ +import os.path +import sqlite3 + +DB = None +cursor = None +misc_path = "./app/Database/Msg/Misc.db" +# misc_path = './Msg/Misc.db' +if os.path.exists(misc_path): + DB = sqlite3.connect(misc_path, check_same_thread=False) + # '''创建游标''' + cursor = DB.cursor() + + +def get_avatar_buffer(userName): + sql = ''' + select smallHeadBuf + from ContactHeadImg1 + where usrName=?; + ''' + cursor.execute(sql, [userName]) + result = cursor.fetchall() + # print(result[0][0]) + if result: + return result[0][0] + return None + + +if __name__ == '__main__': + get_avatar_buffer('wxid_al2oan01b6fn11') diff --git a/app/components/CAvatar.py b/app/components/CAvatar.py index 09dbb09..4330cb5 100644 --- a/app/components/CAvatar.py +++ b/app/components/CAvatar.py @@ -32,7 +32,8 @@ class CAvatar(QWidget): StartAngle = 0 # 起始旋转角度 EndAngle = 360 # 结束旋转角度 - def __init__(self, *args, shape=0, url='', cacheDir=False, size=QSize(64, 64), animation=False, **kwargs): + def __init__(self, *args, shape=0, url='', img_bytes=None, cacheDir=False, size=QSize(64, 64), animation=False, + **kwargs): super(CAvatar, self).__init__(*args, **kwargs) self.url = '' self._angle = 0 # 角度 @@ -50,7 +51,10 @@ class CAvatar(QWidget): self.setShape(shape) self.setCacheDir(cacheDir) self.setSize(size) - self.setUrl(url) + if img_bytes: + self.setBytes(img_bytes) + else: + self.setUrl(url) def paintEvent(self, event): super(CAvatar, self).paintEvent(event) @@ -172,6 +176,14 @@ class CAvatar(QWidget): """ self.shape = shape + def setBytes(self, img_bytes): + self._pixmap = QPixmap() + if img_bytes[:4] == b'\x89PNG': + self._pixmap.loadFromData(img_bytes, format='PNG') + else: + self._pixmap.loadFromData(img_bytes, format='jfif') + self._resizePixmap() + def setUrl(self, url): """设置url,可以是本地路径,也可以是网络地址 :param url: @@ -278,6 +290,8 @@ if __name__ == '__main__': app = QApplication(sys.argv) w = CAvatar( + img_bytes=b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x84\x00\x00\x00\x84\x08\x00\x00\x00\x00t/\xdc{\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x00\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x0e\x8fIDATx\xda\xed\x9b[\x8c]\xd7Y\xc7\xbf\xff\xb7\xd6\xde\xfb\x9c3w\xdf&\xbe\xdf\x9d\xa4\xbe\xc4\x89krmI\xdc\x06\xa5i\xa0$\x95\xa0\x95\x02U\x0bBH(\\\xfa\x80\x10<\xf0\xd6\x07\xfa\x80D\x1e\xa0P\xa2\x02-\xa1)%j\x13\xd2\xe6~O\x9a\xc4J\x9a\xc4\x8e\xeb\xcb8\xf8\x9eq\xec\x8c\xe7~\xf6\xdek}\x7f\x1e\xce\x8c\xc7g:\x05\xe7\xa0\x11\x8d\xaf\x85m\xa1o\xcf\xdb\xc7d(]\xb8\xe2\xc6\x1d\xd7\xd4\x9cYR\x0e~{/v\xdce\x89c\xa4\x93(\x8a\xb9YG\xe9\x87zox\xf9\xe4\xc3\xab\xd6\xa4!\xb1\x8b\xdb\x06H\x81\x18\xc2\x8e\xab\xde\xdd\xd7\x7f\xf4x\xfb\x95_Y0\xbf\xcd\x8fV\x10\x92\xfa\xab\xafiu\xad\xef\xff\xa8\xad\xc3k.N\x8c\xde\xe6\x02\x91X\xfb\xc8\x96\xbb\xef\xef{q%9W\xa7I8qq\xe9\xaa\xba\x7f\xe4\xaf\xd0}CI\xa9w\x94\x92\xe4|M\x92\xc1\x1f\xffp\xa0\\\xbaz\xed-\xcb\x02\xc5I\x9c\x93\x89F\xc9\xdb\xf4\xa6u#oEK"/\xae\x97\x13a\x8aP\xab{\x89\x9ai\x10I\xd2h\xa4\xd7M\xcep\xf0\xe0P\xb1\xf7\x89\x87\xfb\xcdT\xa35\xbd\xf7\x02Q\xb42Z\xe9\xbd\xb3\\e\x19\xa3\x83\\,\x88Lz\xd5\xec\xfa\xe6\xa9E\x7f\xb2\xcd\x19\xd3\xa0\xa5y\xdb\xf7\xd0\x01\xae\xfe\xf2\x1as\x05\xc5ISVq\x81\xeb(\x13\x83\x99\xa51\n`\x93\x12\xa4\xc1\x899\x03g\xf4\x1c\xc1\r?\xb87\xb5\xfdeU\x8f\xc9\xday\xae,3Ww\xce\x87\x03\x7f\xb3/n\xf9\xdaV\x9a+t:\xfd\xec\x1e\x93,\xd5\x99(c\xc6\xd2CCC\x14\xce\xd1D\x83\xe8\xcc1-\xa9\xa3~hl,\xf3y\\w\xe7\x1d\xedCY-\x94\xd5\x10\x8b\x9d\x0f\x1c\xf5\xb7\xfd\xc1<\x12\x92\x80\xd6\x1c\x04fuV\x02OD\x07\x19T\x11\x188q\x1dQ\xd5\x04\xe6\xc1\x99<\x18$\xb4]\xb5\xf2\xe4@\x84\xdf\xf6\xa5\xb5C\xbe\xeaL\xbc!>\xfb\xd0\x01\xd7yko\xae\xa9\x16\x89L\x0b\xa2\x82\xd9\xc6\xd4 \xb32d\x05\x1f\x18\xea\xd9\xbe\x99>LlCd\x1c\x1e\xec\xad\x00\xcef\xda\x86 \xbe\xef\x9f_\tze\xd7\xe9p\xd3\xe7{\x05\x9a\x87\xe7\xff\xb1\xdf\xa5\xd6\xd3\xd9\xbd\xf6\xc6++\x88\xe2%\x9ck\xa3~\xfa\x9b\x01S\x98\x90*c\x99\xaf\x8f<\xf2\x83\xb0\xf9\x97\x95\xa1\xf1\xc9A\xd3\xf2\xfb\x8f\xf7\xddq\xcf\xd5\xa9\x988kd\xb2\x84PI\x15C\x89dt\xc9\x8a\x97\x93\xb0/P\x0f\xad\xee\x8db\x95#\x8f\x7f8?J\xc6\xc1\x93\xaf\xfd\xe4\x86\xdf\\\xee\x94\xe6&\xee\x92\xa2\xc2&\x08\x98\x12A%B`\xa20=\xfe\xd8\x13\xf3v|nY\x14g"0g\xaaq\xffw\xeb\xdd/\x9e\xba\xf7\xc6\x89\x84\xeb\x9c\xfc\x9eP\xf3&\xd9\xce\x9d\x06\xcb\x13\xcf\rW\x88de\xb9\xe8W7V\xbb*\x95\x04\xa3\xfb\x1e~\xe6\xc3\xfb\xd6\xda\x94m@8M\x12\x06(\x9dF:\x13GI\xeb\xbb\xbfs\xb0\xe7\xf77v$\xb9\x06O:3\x04\x05\xaf\x1b\xda\'{~\xb2\xb9\xcdEN\xe6j\x80\x882B\x11\xad|\xf1\xfb\x07T\xb6v\xbdw|\xc1\xe7\xd6\xa9\x14\xd0\xb6\xed\xb7\xb8\xb2f\x92\xc4m\xaf\x1fy\xe7G_\xeb\xd0sL\x94\xc04\xeb(\xb2\xc2\x9bc\x84)\xf3\xddO\xbdT\xbd\xe3\x8b\xf3\x13\xe6ItA\x11|\x84\x037\xfd\xe5\xb1\xbf\xdec;\x87k\xc0\x84;\x07i>\x06u\x8cq\xfc\xcd\x9f\xf6\xf5\xa7\xba\xed\x8f\x16\xbe;\xb8hSn\xc1%%{\xf2\x98Y\t\x14X\xb4\xdf?\xbf\xf6\xf38\x1b:(Nl\x1aD\x02\xc4$OH\x8d\xbb\xdex\xb2\xbe\xfc\xcb\xd7u0\xba`e\xadT\x8d\x12\x1c(l\x93")RD\xe7\x08C#h0\x00.\x8e\x1f\xdb\xb3\xfb\xb5\x81\xaa\xc0_\xb7H\xb6\x92\xa52\x95 RG\xc5\xe2/\x0e/\x08\xbbv\xb3}\xe0\xe0x\xdb\x94q@8]\'\xdc@\xa5V*a\x07~\xfc\xf6\xc9\xee;\xefXn\xfd\x03\xebU\xd4["\xa7\xdf]\xb1\xba\xf0j \xa3\xf94u\r\xff\xa5\xc2(p&c\xc7\xf7\xee~kt\xacm\xd5\xe9T\xe5\x13\t\xcaX\x89"\xb1D\xd5\x0c6\xbe\xf3?\xde[06d\xc9G\xeboH\xa9\x93NFAk\x86\x10\x8d\xffj7\xadh\x1b\xf9\xf93?\x8f=\xb7\xff\xc6Ro\xc3\x0f\x8c\xfd\xf1\xbc$\xf8\xdc\xeb\xfb\xf7/\xf8\xf35#\x15\x8dZ\x96\x11\xddU\x11\xa3\x8a\xd0\x9c\xe3\x9b\x8f~\x84\xb1#\xa3\x95\x9eUk~e\xe9\xb7\x9e)\xbb\xf2\x07O\xec\xd8\x94\x8b\xa3\xa4\x16\x89\xfc\xf0s\x8f\xf6\xf7\x1c\xae@\xfc\xf2?\xbdR4\xb8Is\x8c\xb1\xa2\xbe\x99!\xa9<\xf7\xea\xfa\xcec\xfbG\xe7\x7f\xea\xfa\rm\x12\xb0\xf7\xf5\rB\xaay\x97\x9f\x1a\xdf\xf7\xd3{ky\xa6(\x8dZ\xf3\x93^\xdbEV\x96\xac\x7f\xeeH\xd1\xb1l\xd5\x96\r+\xab\'NE;\xfd\xf7\x1f\x9c9\xf1\xd5\xf5\xde\xa2\x9a\xa5CG_}\xf9h\xdeY\xaaI\xb2\xe0\xb7\xd6\x01\xe6\xa7,\xd4Yl\x82\xa0\xc8\x17\xd7?\xfdz\xde\xbe\xfc\xfam\xcbj\x96\xd4\xb5xe\xb8\xb7\xad\xf4\x11\xde\x92\x81\x9co~j\xa3D53a\xd5M\xe6:!\xb1\xf1\xc5wo=:x\xc5\xf2\x9ev\'\xe1\xe8\xb1\xb2"\xfb\x1c_\xdd\xb4\xc2\xb2$\x1f;\xbd\xf7\xcd\x83\x83\x03d\x99*C\xf5\x9e\x9b\xb3hv\xd6\xdbR46[Gte\xe7\xcd\xdb\x8f\xd4\x17t\xa5!#\xea\xa9\xbe\xf1\xfa\xf85\xa9DoQR\xa5\x9d8q\x95\x830\x880=\x1b:\xd2zE\xcbl\xf3U\x96\xb0t$\xf6\x9d\xaa\x85\xf2K\xd9\x8bG\x9f\xba9\x7f\xf6\xf8\xf0\xc0\xe9\xd14\xe9\xea9\xed0\xae\xa2\x8b\xcbg\xb6\xcdO\xf4\xac\xc7WFi\x86pTZ\xba\xca\x993\x15\x81\x8f\xe5sG\xe6_i\nz\xcb\x13\x85\x1b?Z8\x15\x94\x14\xd5\xb3\xc9VH\x83x+UIOp\xf4\xa0\x85$Y\x97\xbe\x15O\xed\xb9\xde\x8e\x9c\t\xc9\xc6\r\x1b\x92G\xcf\x98T"]\xdf!\xfd\xb3OM\xa5\xeeT-\x1d\xa79+1\xd0\x91E\xca\xe8$w\xfb_\xaal\xe9\xf4\x88\xce\xe8\x83P\xfdXLJg\x12\'*\xfe\t\xe5\x92F\xb6AB\xa8g\x8e\x88+\xf0\x0fE\x9e\r\xbf\xf3\x85\xaf|\xf6\x0c\xb1\xaa-\xff\xbb}\xc1G\x13\xb8z\xfb\x86\x95\x0eg}\x15\x08\xfa\xb2\xd9D)\x80D\xaf\xb4\xac \xb2\x0f\xbf;\xda~}\x879\xb1\xa4\x9eh`6:f\xd1G\x1d\x8f\x8ej\xaa\xb0\x08B\x04l\x04v\x08\xcc\x1f\xeaW\xbba\xf1cQ\x87\xab\x03\x83m\xeb\xbc9;\xfa\xed\xc7\xb3\xb4\x84\xa8\x8dm\xfc\xf5\xdbj\xa5\x9emR\x10\x94\xc25C4B\x98\xc9\xe8\x07m\xdd\x15\x94/\xec\xd1y\xeb4\x1a\x90\'\xc6U=\x1fU\xbb3\x8a\xa0\x1e`TD\xc5\xf4n\x1a\x95\x87sm\xbf\xed\x97^\x18f\xc5\xf5\x8d\xb5k\x94\x88\xa3\xbbk\x89Q\x1ct\xdeo\x7f2\r\x06L\xe6\x86\xa0x\x86\xe9\xd7A\x80\xe2\xfb\x1e\x1a\xbcv\xf5R{\xb6\xbf\xb2\xf9\n\x1a\x9dDO\xbb\xfa\xb3Ovm\xf0\x14\xf3\xa5\x08\x89F\xf0l\x86\x80\xf0x\xb0x\xfa\xbdz\x18\xaf\xb8b\xb8\xc7\xa7\xac\xcb\x8a\xd5\xa7G\xa5=\x8f\xea\xee\xd8R\xb3\xe8t*\xab1&h\x0e`P\t\xa2\xd4|+\x9f\xfc\x9et\x97\xb1\xd6\xb3\xbd\xdd\x92\x02\x96F\xb0\xfb\xabwe\x0b\x05T\xb3\x02"4\x17\xb5\x11\xc6\xcf5\xf2\xe2X\xe9\x86\xff%=\xb3\xa4\xf3\xc4\x90\r\xfbXH\xac\xcd\xbf\xefo\x0f\xb7\xa7\xfd\xfda\xf1u]#i\xd4\xa9\x9e\n\x9c\x19\x9b!h\x02E)p\xd7,]\xfd\xfc\x81\xc1\xb6|\xde\x92\xb4\xee\xd0hD\x96\xd9R\x88\x98\xa8\xa5\xa6g\x1bR\xcd\x08\x8a\xb1\x0f\xa1\xba\xa0\xb6\xe4\xa6\xe5\xdf\xa8&\x87\xb7\xa83\x89\x95\x15_?\xe1:\xef\x1f@\xe7\x92\x90\xd1\x89\x9e\xcdX\xa3\xea\xf4\xa4F#\x1d\x98E\x1d\x98\xdfqO\xf1^w\xbd}\xe0\x85\xb6\xe5\x05(\xd1\x19\xd4\x94B\x88Z{57j\x9c^\x99QDlt$)z>s\xab.x\xdf\xb4\xb4\xe8\x02\x13\x11\xce\x9f\xe7\x07+ERs \xc4\xa6r\x1aG\x89:\xbd\x02\xf3e\xb0\xc2b\xcfx\xb5\xef\r7\x86\xd1\xfe\x07\xbf\xf1\xbe\x0b\n\x13\x15\xa2\x91>\x98u\xb8\xe8\xb3\xe8\xcb\xc4\xceM4)B\xd1\xfa`\x90+n\\\xb5\xb8+\xb2\x88=\tM\x0c\x02c=D/\xb5\x84"T\xea\xd4\x1e\xea\xb42\xd0`\x89w\x11(\xed\xd8\xbf\xedcm\xdb\'+\xd8\xf5\xc8GY\x107\x95Z#$\x1d\xed\xc2\xae\x00\x15\x9e\xdbjhTi\x83\x92b\xc9Rbx Ij\x8b\x11+\tb\x8c\xaa\xcey\'\xa9\nM\xcek>5{\xcc\x18\x92Rq\xc6\xe7\x87\x1e\xf9\xd9p\xc7=_\x18\xfb\xa7\x97\xf4\x95\x9b\x17E\x7fN\xa9C\xfaR\xa4gm\x12M8\xbd\xa0\xd3\x98\xa4!\xac\xaf\xf9\x0f\x1ey\xb3\xae+\x17\x05\xa3@E\xa20\x86R3\x9d\xb1\xc5\xd0\x04\x11\x90&c\x08?xmtt\xa0\xed\xda_\xdb\xa1\xbd__\xfb\x9f~$:\xb3svk\xfc`\x90\xb5e\x1a\xd0\xe8\x07\x9c#\n\x9a.\xdf\xfaN\xba\xd9\x15\xed\xe9\t\xad\xdd\xd8\x053\nI\x07U\xe7\xac\xa63\xb6g\xa7\xc5\x8e\xa8\x80\xdbpr_\xbef\xfbg\xd6%\xa5u\xde\xb9|dC\xb3\xde\xc0\x99H\x1c\xab\xd7\xbd64\xe5\xdc\x9fA\xba\x7f\xe7)Y\xa9\xec\xba\xbdvp\xc5\xed,\x12\x90\x02%\x85P\xa9\x81\xa4^\x18\x820&!\xbde\xfb{\x83\xcbV\'&i\xa9\xdd\xb7\x8e\xd7\xc6*\xe7\x1a"`\xf3\xdaF\\ThP\xb5f\x131\xc8\x86\xd5E\xad^\xb1ewGICb\x10\x80\x86\x86<2\x87\x8bJB\x90D\xd1\x02\xb5\x1b-\x82N"\x83\xe6\xde &Sb\xa4\xc8\xc2\x8a3\xe7\x83sFLS\n\xd1\\\xdaC\x1aM\xbd\x17q\x9cL\xc6)\x0e!\xebp\x86\x19*\xd8&\xd9 \xc2\xb1\xac$,\xa2(,\x8a\x8395\x1f\xa1r\xb6cD\x8d\xce\x99\xf7\x9c\xa9\xbf\xa2\xa4\xf3\xa2l\xb4\xa2qN^\xaf\x14\xf8\nDf\xa8\xdb\x9aN"\x023\x1f\xc4\xab\xc5(NH\x07\xa7Z\x89q\xaax\x84D\xc4H\xf5\xb34\x91\xe8@B\xed\xbc\x89\x82\x95\xb1\xda6s\xff\xad\tB#,W\xd2\xe8\xb3FAS7Z\x18\xcf\xdc\x94\xd4\xa9\x96\x8e\x97\xd0Tg\xaa\xca\'Z(!:\rM2\x16\x0b\xb9\xfav\xc1E\'?11QS\x80f*F \x05\xa9\x12\x85S\x9b\xe9C=h-\x99\xf13\tH\x8a\xa9\xd0\xa6\xc9\x98\xc5\x88\xf75@f\x18\xba4\xeb\x84\x89\x98\x906YcR\x8ch\x8c\xd1l\nbl\xbcd\xcd\xdb\xcc=7*\xe8Hh\xd3\xd0\x8d\xe0\xf8\x10;\xdb`3\xb5\xa7\xcf;\xa9Y^\x13i\\C\xbf\xd98"\xe8\xa1\x11\xeb\xae\xaa5\xa6~\xcd\x97B\xd8\xe4\xeco\xf2\x84\xc6\x800=U/{:\xa8q.\x10\x17X\xa0\x13\x03J\xd9\x1b\xa4\xbb\x1a\xe6\xb6\x15\x12@\xb8\xc8\x8f\xa2-H8\xd3\xf4\xe9\xd2\x86\xb3&\xa6\x81\xc9\x81\x83.[\x98\xccq.Eq"f\x8eG\x86\xb18\x99\xb9\x1dz\t\x10\x84\xa8+S\x8c<\xdeWV\xd7\xcc\xa5\xdf\xdd\xd8\xe6\n\xa81\xef\xa3\xaeP\\\xea\\\xf4\xbc\x15]\x8c\x9e\x1f>\xfd\xac\xc3\xda\x95\xca\x8b\xb5\xfd\x1b\x0b\x16T\x04\xf8\xb0/\xce[,\x98\xd1\xbb\\\x02\x044z\x1c\x7fl\xd7\xf1q\xb8\x1bz\\\xa0\xcdI\x8c\xae\xac\x14\x86\xf8\xce \x16\xcf\x9b6\xc0\xbe,Id\xa3i\xa5\xd6\xd1\xdb\xbb\xf6\x13;\x1cA77\xad\xa8\x8cV\xeb\xd9\xae\x87$\xb9\xba\xcbh\xfa?\xbc\x0e\x1d\xcf\xd8s\xef@\xe1\xabH\x181G\xcd4&\xca\xa7~tX\x16m\xb3Y&i\x97\x00AT\xc7\x1dc\x97\xc1\x11\x91P\x9b\xd36U\x8e\xa7?;\xbc\xa0\xbeu\xa3\xcd\xa2\xca\x98\xfb\xbf\xdb\xc0\x8a\xaa\x04U"\x84D\x04s\x1b\x1e\x13E\xd5dh$\xef\xaeVl\x96=\x97\x00A\x8d\xde\x08\x81\x01\x86\x99\x1d\xf0\x0c\x82\x08\xe2\x83\x13\xf3\xf5t6A\\\x8a\x9f@\xf4\x91\r\xf7M\x05q\xf1I\xa9\x88H\xd4$x#\xa2\x9f}\xb4z\t\x92\xf8\xdf[\xff\xe7\xfe\xa6\xa6\x05\xd1\x82hA\xb4 Z\x10\x1f\xfbjA\xb4 Z\x10-\x88\x16D\x0b\xa2\x05\xd1\x82\xf8\x7f\x01\xf1\xdf\x91\xd3\xe9`7\x9a\x1c\x88\x00\x00\x00\x12tEXtexif:ExifOffset\x00620\x1a\xa3x\x00\x00\x00\x12tEXtexif:ImageLength\x000\xc1\xc5N\xce\x00\x00\x00\x11tEXtexif:ImageWidth\x000/\xffv\xa0\x00\x00\x00\x12tEXtexif:LightSource\x000x\x05kH\x00\x00\x00\x00IEND\xaeB`\x82' + , url='https://wx.qlogo.cn/mmhead/ver_1/DpDqmvTDORNWfLrMj26YicorEUREffl1G8FapawdKgINVH9g1icudfWesGrH9LqeGAz16z4PmkW9U1KAIM3btWgozZ1GaLF66bdKdxlMdazmibn2hpFeiaa4613dN6HM4Vfk/132') w.show() sys.exit(app.exec_()) diff --git a/app/components/contact_info_ui.py b/app/components/contact_info_ui.py index d1a0411..681ed2a 100644 --- a/app/components/contact_info_ui.py +++ b/app/components/contact_info_ui.py @@ -9,7 +9,7 @@ from .CAvatar import CAvatar # 自定义的item 继承自QListWidgetItem class ContactQListWidgetItem(QListWidgetItem): - def __init__(self, name, url): + def __init__(self, name, url, img_bytes=None): super().__init__() # 自定义item中的widget 用来显示自定义的内容 self.widget = QWidget() @@ -18,7 +18,7 @@ class ContactQListWidgetItem(QListWidgetItem): self.nameLabel.setText(name) # 用来显示avator(图像) self.avatorLabel = CAvatar(None, shape=CAvatar.Rectangle, size=QSize(60, 60), - url=url) + url=url, img_bytes=img_bytes) # 设置布局用来对nameLabel和avatorLabel进行布局 self.hbox = QHBoxLayout() self.hbox.addWidget(self.avatorLabel) diff --git a/app/person.py b/app/person.py index 07f0d91..a614328 100644 --- a/app/person.py +++ b/app/person.py @@ -45,6 +45,7 @@ class ContactPC: self.alias = contact_info.get('Alias') self.nickName = contact_info.get('NickName') self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl') + self.smallHeadImgBLOG = b'' class Group(Person): diff --git a/app/ui_pc/contact/contact_window.py b/app/ui_pc/contact/contact_window.py index 00050cd..f109f52 100644 --- a/app/ui_pc/contact/contact_window.py +++ b/app/ui_pc/contact/contact_window.py @@ -1,13 +1,9 @@ -from random import randint +from PyQt5.QtWidgets import QWidget, QMessageBox -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel, QMessageBox - -from app.DataBase import micro_msg +from app.DataBase import micro_msg, misc from app.components import ContactQListWidgetItem from app.person import ContactPC from .contactUi import Ui_Form -from ...Ui.Icon import Icon # 美化样式表 Stylesheet = """ @@ -57,19 +53,6 @@ class ContactWindow(QWidget, Ui_Form): 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, 'None', self.listWidget) - myinfo_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget) - tool_item = QListWidgetItem(Icon.MyInfo_Icon, 'None', self.listWidget) - 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) - self.stackedWidget.addWidget(label) - self.stackedWidget.addWidget(label) self.listWidget.setCurrentRow(0) self.stackedWidget.setCurrentIndex(0) @@ -89,8 +72,9 @@ class ContactWindow(QWidget, Ui_Form): 'smallHeadImgUrl': contact_info_list[7] } contact = ContactPC(contact_info) + contact.smallHeadImgBLOG = misc.get_avatar_buffer(contact.wxid) # pprint(contact.__dict__) - contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl) + contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl, contact.smallHeadImgBLOG) self.listWidget.addItem(contact_item) self.listWidget.setItemWidget(contact_item, contact_item.widget) From 5849b8f692138f649c9875f53b8db5fff8b74ef4 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 15 Nov 2023 22:59:25 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E8=81=94=E7=B3=BB?= =?UTF-8?q?=E4=BA=BA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 27 ++- app/person.py | 13 ++ app/ui_pc/contact/contactInfo.py | 132 +++++++++++ app/ui_pc/contact/contactInfoUi.py | 92 ++++++++ app/ui_pc/contact/contactInfoUi.ui | 168 ++++++++++++++ app/ui_pc/contact/contactUi.py | 8 +- app/ui_pc/contact/contactUi.ui | 4 +- app/ui_pc/contact/contact_window.py | 36 ++- app/ui_pc/contact/userinfo/__init__.py | 9 + app/ui_pc/contact/userinfo/userinfo.py | 15 ++ app/ui_pc/contact/userinfo/userinfoUi.py | 121 ++++++++++ app/ui_pc/contact/userinfo/userinfoUi.ui | 280 +++++++++++++++++++++++ 12 files changed, 874 insertions(+), 31 deletions(-) create mode 100644 app/ui_pc/contact/contactInfo.py create mode 100644 app/ui_pc/contact/contactInfoUi.py create mode 100644 app/ui_pc/contact/contactInfoUi.ui create mode 100644 app/ui_pc/contact/userinfo/__init__.py create mode 100644 app/ui_pc/contact/userinfo/userinfo.py create mode 100644 app/ui_pc/contact/userinfo/userinfoUi.py create mode 100644 app/ui_pc/contact/userinfo/userinfoUi.ui diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 5f03fbf..c1725e9 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,12 +4,11 @@ - @@ -659,7 +657,8 @@ - diff --git a/app/person.py b/app/person.py index a614328..c03548e 100644 --- a/app/person.py +++ b/app/person.py @@ -1,9 +1,11 @@ import os.path from typing import Dict +from PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap from app.DataBase import data +from app.ui_pc.Icon import Icon # from app.Ui.Icon import Icon @@ -46,6 +48,17 @@ class ContactPC: self.nickName = contact_info.get('NickName') self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl') self.smallHeadImgBLOG = b'' + self.avatar = QPixmap() + + 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.scaled(60, 60, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) class Group(Person): diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py new file mode 100644 index 0000000..20b2d8e --- /dev/null +++ b/app/ui_pc/contact/contactInfo.py @@ -0,0 +1,132 @@ +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * + +from app import person +from app.DataBase import output +from app.Ui.Icon import Icon +from .contactInfoUi import Ui_Form +from .userinfo import userinfo + + +class ContactInfo(QWidget, Ui_Form): + exitSignal = pyqtSignal() + urlSignal = pyqtSignal(QUrl) + + # username = '' + def __init__(self, contact, me: person.Me = None, parent=None): + super(ContactInfo, self).__init__(parent) + self.setupUi(self) + self.contact = contact + self.view_userinfo = userinfo.UserinfoController(self.contact) + + # self.btn_analysis.clicked.connect(self.analysis) + # self.btn_emotion.clicked.connect(self.emotionale_Analysis) + # self.btn_report.clicked.connect(self.annual_report) + self.btn_back.clicked.connect(self.back) + self.Me = me + # self. + 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.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.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) + 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) + + def toolButton_show(self): + self.toolButton_output.showMenu() + + def analysis(self): + 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.report = report.ReportController(self.contact) + # self.report.show() + + def emotionale_Analysis(self): + 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: + self.outputThread = output.Output(self.Me, self.contact.wxid) + elif self.sender() == self.toCSVAct: + print('开始导出csv') + self.outputThread = output.Output(self.Me, self.contact.wxid, type_=output.Output.CSV) + print('导出csv') + elif self.sender() == self.toHtmlAct: + print('功能暂未实现') + QMessageBox.warning(self, + "别急别急", + "马上就实现该功能" + ) + return + self.outputThread.progressSignal.connect(self.output_progress) + self.outputThread.rangeSignal.connect(self.set_progressBar_range) + self.outputThread.okSignal.connect(self.hide_progress_bar) + self.outputThread.start() + + def hide_progress_bar(self, int): + reply = QMessageBox(self) + reply.setIcon(QMessageBox.Information) + reply.setWindowTitle('OK') + reply.setText(f"导出聊天记录成功\n在.\\data\\目录下") + 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) diff --git a/app/ui_pc/contact/contactInfoUi.py b/app/ui_pc/contact/contactInfoUi.py new file mode 100644 index 0000000..aa973a1 --- /dev/null +++ b/app/ui_pc/contact/contactInfoUi.py @@ -0,0 +1,92 @@ +# -*- 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(817, 748) + self.horizontalLayout = QtWidgets.QHBoxLayout(Form) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setSpacing(0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.frame = QtWidgets.QFrame(Form) + self.frame.setFrameShape(QtWidgets.QFrame.NoFrame) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setSpacing(0) + 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(self.frame) + self.label_remark.setMaximumSize(QtCore.QSize(16777215, 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(self.frame) + self.btn_analysis.setStyleSheet("") + self.btn_analysis.setFlat(True) + self.btn_analysis.setObjectName("btn_analysis") + self.horizontalLayout_3.addWidget(self.btn_analysis) + self.btn_emotion = QtWidgets.QPushButton(self.frame) + self.btn_emotion.setFlat(True) + self.btn_emotion.setObjectName("btn_emotion") + self.horizontalLayout_3.addWidget(self.btn_emotion) + self.btn_report = QtWidgets.QPushButton(self.frame) + self.btn_report.setFlat(True) + self.btn_report.setObjectName("btn_report") + self.horizontalLayout_3.addWidget(self.btn_report) + self.btn_back = QtWidgets.QPushButton(self.frame) + self.btn_back.setFlat(True) + self.btn_back.setObjectName("btn_back") + self.horizontalLayout_3.addWidget(self.btn_back) + self.toolButton_output = QtWidgets.QToolButton(self.frame) + 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.verticalLayout.addLayout(self.horizontalLayout_3) + self.stackedWidget = QtWidgets.QStackedWidget(self.frame) + 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.horizontalLayout.addWidget(self.frame) + + 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", "导出聊天记录")) diff --git a/app/ui_pc/contact/contactInfoUi.ui b/app/ui_pc/contact/contactInfoUi.ui new file mode 100644 index 0000000..18591fb --- /dev/null +++ b/app/ui_pc/contact/contactInfoUi.ui @@ -0,0 +1,168 @@ + + + Form + + + + 0 + 0 + 817 + 748 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 16777215 + 100 + + + + + 12 + + + + + + + + + + + + + + 统计信息 + + + true + + + + + + + 情感分析 + + + true + + + + + + + 年度报告 + + + true + + + + + + + 退出 + + + true + + + + + + + 导出聊天记录 + + + + ../../data/icons/output.svg + ../../data/icons/output.svg + + + + false + + + QToolButton::MenuButtonPopup + + + Qt::ToolButtonTextBesideIcon + + + true + + + Qt::NoArrow + + + + + + + + + 1 + + + + + + + + + + + + + diff --git a/app/ui_pc/contact/contactUi.py b/app/ui_pc/contact/contactUi.py index 2fb6c1d..aeada21 100644 --- a/app/ui_pc/contact/contactUi.py +++ b/app/ui_pc/contact/contactUi.py @@ -35,17 +35,11 @@ class Ui_Form(object): self.horizontalLayout.addLayout(self.verticalLayout) self.stackedWidget = QtWidgets.QStackedWidget(Form) self.stackedWidget.setObjectName("stackedWidget") - self.page = QtWidgets.QWidget() - self.page.setObjectName("page") - self.stackedWidget.addWidget(self.page) - self.page_2 = QtWidgets.QWidget() - self.page_2.setObjectName("page_2") - self.stackedWidget.addWidget(self.page_2) self.horizontalLayout.addWidget(self.stackedWidget) self.horizontalLayout.setStretch(1, 1) self.retranslateUi(Form) - self.stackedWidget.setCurrentIndex(1) + self.stackedWidget.setCurrentIndex(-1) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): diff --git a/app/ui_pc/contact/contactUi.ui b/app/ui_pc/contact/contactUi.ui index 4a432b1..b11ff70 100644 --- a/app/ui_pc/contact/contactUi.ui +++ b/app/ui_pc/contact/contactUi.ui @@ -71,10 +71,8 @@ - 1 + -1 - - diff --git a/app/ui_pc/contact/contact_window.py b/app/ui_pc/contact/contact_window.py index f109f52..7ee62ec 100644 --- a/app/ui_pc/contact/contact_window.py +++ b/app/ui_pc/contact/contact_window.py @@ -1,8 +1,10 @@ +from PyQt5.QtCore import QThread, pyqtSignal from PyQt5.QtWidgets import QWidget, QMessageBox from app.DataBase import micro_msg, misc from app.components import ContactQListWidgetItem from app.person import ContactPC +from .contactInfo import ContactInfo from .contactUi import Ui_Form # 美化样式表 @@ -45,6 +47,7 @@ HistoryPanel::item:hover { class ContactWindow(QWidget, Ui_Form): def __init__(self, parent=None): super().__init__(parent) + self.show_thread = None self.setupUi(self) self.setStyleSheet(Stylesheet) self.init_ui() @@ -60,6 +63,30 @@ class ContactWindow(QWidget, Ui_Form): if not micro_msg.is_database_exist(): QMessageBox.critical(self, "错误", "数据库不存在\n请先解密数据库") return + self.show_thread = ShowContactThread() + self.show_thread.showSingal.connect(self.show_contact) + self.show_thread.start() + + def show_contact(self, contact): + contact_item = ContactQListWidgetItem(contact.nickName, 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) + + # 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 @@ -73,11 +100,6 @@ class ContactWindow(QWidget, Ui_Form): } contact = ContactPC(contact_info) contact.smallHeadImgBLOG = misc.get_avatar_buffer(contact.wxid) + contact.set_avatar(contact.smallHeadImgBLOG) + self.showSingal.emit(contact) # pprint(contact.__dict__) - contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl, contact.smallHeadImgBLOG) - self.listWidget.addItem(contact_item) - self.listWidget.setItemWidget(contact_item, contact_item.widget) - - def setCurrentIndex(self, row): - print(row) - self.stackedWidget.setCurrentIndex(row) diff --git a/app/ui_pc/contact/userinfo/__init__.py b/app/ui_pc/contact/userinfo/__init__.py new file mode 100644 index 0000000..6d32454 --- /dev/null +++ b/app/ui_pc/contact/userinfo/__init__.py @@ -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 : ··· +""" diff --git a/app/ui_pc/contact/userinfo/userinfo.py b/app/ui_pc/contact/userinfo/userinfo.py new file mode 100644 index 0000000..5a6ac0b --- /dev/null +++ b/app/ui_pc/contact/userinfo/userinfo.py @@ -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) diff --git a/app/ui_pc/contact/userinfo/userinfoUi.py b/app/ui_pc/contact/userinfo/userinfoUi.py new file mode 100644 index 0000000..8154cf6 --- /dev/null +++ b/app/ui_pc/contact/userinfo/userinfoUi.py @@ -0,0 +1,121 @@ +# -*- 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(800, 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("background:transparent;border-width:0;border-style:outset") + 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", "曹雨萱")) diff --git a/app/ui_pc/contact/userinfo/userinfoUi.ui b/app/ui_pc/contact/userinfo/userinfoUi.ui new file mode 100644 index 0000000..3bba2de --- /dev/null +++ b/app/ui_pc/contact/userinfo/userinfoUi.ui @@ -0,0 +1,280 @@ + + + Frame + + + + 0 + 0 + 800 + 720 + + + + IBeamCursor + + + true + + + true + + + Frame + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 6 + + + + + + 80 + 80 + + + + + 80 + 80 + + + + + + + ../../../a_img/be0fa6c0c4707fb5f7b37b660de826d3.jpg + + + true + + + + + + + + 0 + 30 + + + + + 16777215 + 30 + + + + + 15 + + + + 曹雨萱 + + + + + + + + 0 + 30 + + + + + 16777215 + 30 + + + + 昵称:997 + + + + + + + + 0 + 20 + + + + + 16777215 + 20 + + + + 账号:TextLabel + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + + 15 + + + + 备注名 + + + + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + 15 + + + + ArrowCursor + + + false + + + + background:transparent;border-width:0;border-style:outset + + + + 曹雨萱 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 24 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + From 3ceb9e23401792f19fc1110c39a493286bb2818a Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 15 Nov 2023 23:53:39 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddb=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=A9=BA=E6=A0=BC=E8=B7=AF=E5=BE=84=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 76 ++++++++++++++++---------------- app/DataBase/msg.py | 11 +++++ app/DataBase/output_pc.py | 52 ++++++++++++++++++++++ app/Ui/decrypt/decrypt.py | 6 ++- app/Ui/mainview.py | 4 +- app/person.py | 2 +- app/ui_pc/contact/contactInfo.py | 17 +++++-- 7 files changed, 125 insertions(+), 43 deletions(-) create mode 100644 app/DataBase/msg.py create mode 100644 app/DataBase/output_pc.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c1725e9..d2bda6c 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,12 +4,14 @@ - @@ -658,7 +659,8 @@ - diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py new file mode 100644 index 0000000..ea8ed4a --- /dev/null +++ b/app/DataBase/msg.py @@ -0,0 +1,11 @@ +import os.path +import sqlite3 + +DB = None +cursor = None +misc_path = "./app/Database/Msg/MSG0.db" +# misc_path = './Msg/Misc.db' +if os.path.exists(misc_path): + DB = sqlite3.connect(misc_path, check_same_thread=False) + # '''创建游标''' + cursor = DB.cursor() diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py new file mode 100644 index 0000000..b1bffb2 --- /dev/null +++ b/app/DataBase/output_pc.py @@ -0,0 +1,52 @@ +import os + +import numpy as np +import pandas as pd +from PyQt5.QtCore import pyqtSignal + + +class Output(QThread): + """ + 发送信息线程 + """ + progressSignal = pyqtSignal(int) + rangeSignal = pyqtSignal(int) + okSignal = pyqtSignal(int) + i = 1 + CSV = 0 + DOCX = 1 + HTML = 2 + + def __init__(self, ta_u, parent=None, type_=DOCX): + super().__init__(parent) + self.sec = 2 # 默认1000秒 + self.ta_username = ta_u + self.msg_id = 0 + self.output_type = type_ + self.total_num = 0 + + @log + def to_csv(self, conRemark, path): + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}" + filename = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}/{conRemark}.csv" + last_timestamp = 1601968667000 + columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"] + df = pd.DataFrame() + df["用户名"] = np.array(list(map(lambda x: x[7], messages))) + df["消息内容"] = np.array(list(map(lambda x: x[8], messages))) + df["发送时间"] = np.array(list(map(lambda x: time_format(x[6]), messages))) + df["发送状态"] = np.array(list(map(lambda x: x[3], messages))) + df["消息类型"] = np.array(list(map(lambda x: x[2], messages))) + df["isSend"] = np.array(list(map(lambda x: x[4], messages))) + df["msgId"] = np.array(list(map(lambda x: x[0], messages))) + df.to_csv(filename) + # df.to_csv('data.csv') + print(df) + self.progressSignal.emit(self.num) + + def run(self): + if self.output_type == self.DOCX: + return + elif self.output_type == self.CSV: + # print("线程导出csv") + self.to_csv(self.ta_username, "path") diff --git a/app/Ui/decrypt/decrypt.py b/app/Ui/decrypt/decrypt.py index 981879b..7204a7c 100644 --- a/app/Ui/decrypt/decrypt.py +++ b/app/Ui/decrypt/decrypt.py @@ -51,7 +51,11 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): def get_db(self): self.db_path, _ = QFileDialog.getOpenFileName(self, 'Open file', r'..', "Database files (*.db)") if self.db_path: - if self.db_path.isascii(): + if ' ' in self.db_path: + self.label_db.setText('数据库未就绪') + QMessageBox.critical(self, "错误", "db文件路径请不要带有空格\n可以放在D:\\\\data 目录下") + self.db_path = '' + elif self.db_path.isascii(): self.label_db.setText('数据库已就绪') return self.db_path else: diff --git a/app/Ui/mainview.py b/app/Ui/mainview.py index 16ddfff..74b6129 100644 --- a/app/Ui/mainview.py +++ b/app/Ui/mainview.py @@ -12,11 +12,13 @@ from PyQt5.QtGui import * from PyQt5.QtWidgets import * from app import config +from app.DataBase import data from app.Ui import mainwindow from app.Ui.Icon import Icon from app.Ui.chat import chat from app.Ui.contact import contact from app.components.prompt_bar import PromptBar +from app.person import Me class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): @@ -29,7 +31,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.setWindowIcon(Icon.MainWindow_Icon) self.setAttribute(Qt.WA_AttributeCount) - + self.Me = Me(data.get_myinfo()) self.chatView = chat.ChatController(self.Me, parent=None) self.lay = QHBoxLayout() self.page_chat.setLayout(self.lay) diff --git a/app/person.py b/app/person.py index c03548e..09f22a4 100644 --- a/app/person.py +++ b/app/person.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap from app.DataBase import data -from app.ui_pc.Icon import Icon +from app.Ui.Icon import Icon # from app.Ui.Icon import Icon diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py index 20b2d8e..9f70d27 100644 --- a/app/ui_pc/contact/contactInfo.py +++ b/app/ui_pc/contact/contactInfo.py @@ -2,7 +2,7 @@ from PyQt5.QtCore import * from PyQt5.QtWidgets import * from app import person -from app.DataBase import output +from app.DataBase.output import Output from app.Ui.Icon import Icon from .contactInfoUi import Ui_Form from .userinfo import userinfo @@ -97,10 +97,21 @@ class ContactInfo(QWidget, Ui_Form): """ self.stackedWidget.setCurrentWidget(self.view_userinfo) if self.sender() == self.toDocxAct: - self.outputThread = output.Output(self.Me, self.contact.wxid) + print('功能暂未实现') + QMessageBox.warning(self, + "别急别急", + "马上就实现该功能" + ) + return + self.outputThread = Output(self.Me, self.contact.wxid) elif self.sender() == self.toCSVAct: + QMessageBox.warning(self, + "别急别急", + "马上就实现该功能" + ) print('开始导出csv') - self.outputThread = output.Output(self.Me, self.contact.wxid, type_=output.Output.CSV) + return + self.outputThread = Output(self.Me, self.contact.wxid, type_=Output.CSV) print('导出csv') elif self.sender() == self.toHtmlAct: print('功能暂未实现') From cc976289024e2b95ce35f6700f8e183f4ecdd4c5 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Thu, 16 Nov 2023 00:06:44 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=83=85=E6=84=9F?= =?UTF-8?q?=E5=88=86=E6=9E=90=E6=95=B0=E5=80=BC=E6=98=BE=E7=A4=BA=E8=BF=87?= =?UTF-8?q?=E9=95=BF=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 28 +++++++++++----------------- app/Ui/contact/emotion/emotion.py | 1 + 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index d2bda6c..3d29d56 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,14 +4,8 @@ - @@ -660,7 +653,8 @@ - diff --git a/app/Ui/contact/emotion/emotion.py b/app/Ui/contact/emotion/emotion.py index f0ede65..c33a4e8 100644 --- a/app/Ui/contact/emotion/emotion.py +++ b/app/Ui/contact/emotion/emotion.py @@ -32,6 +32,7 @@ def emotion_analysis(wxid): emotions.append(s / len(messages)) emotions = np.array(emotions) emotions = np.around(emotions, 3) * 100 + emotions = np.around(emotions, 1) return dates, emotions From e180e58d0f81dcee778ca914d5ca56cab8e85ab5 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Thu, 16 Nov 2023 00:13:49 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E8=A7=A3=E5=AF=86=E5=90=8E=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8A=A0=E8=BD=BD=E8=81=94=E7=B3=BB=E4=BA=BA=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 28 +++++++++++++++------------- app/DataBase/micro_msg.py | 10 ++++++++++ app/ui_pc/contact/contact_window.py | 5 +++++ app/ui_pc/mainview.py | 7 ++++--- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3d29d56..f9c3bb3 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,8 +4,10 @@ - @@ -654,7 +655,8 @@ - diff --git a/app/DataBase/micro_msg.py b/app/DataBase/micro_msg.py index 9a99a2c..f437fad 100644 --- a/app/DataBase/micro_msg.py +++ b/app/DataBase/micro_msg.py @@ -10,6 +10,16 @@ if os.path.exists(micromsg_path): cursor = DB.cursor() +def init_database(): + global DB + global cursor + if not DB: + if os.path.exists(micromsg_path): + DB = sqlite3.connect(micromsg_path, check_same_thread=False) + # '''创建游标''' + cursor = DB.cursor() + + def is_database_exist(): return os.path.exists(micromsg_path) diff --git a/app/ui_pc/contact/contact_window.py b/app/ui_pc/contact/contact_window.py index 7ee62ec..4a0ea48 100644 --- a/app/ui_pc/contact/contact_window.py +++ b/app/ui_pc/contact/contact_window.py @@ -49,6 +49,7 @@ class ContactWindow(QWidget, Ui_Form): super().__init__(parent) self.show_thread = None self.setupUi(self) + self.ok_flag = False self.setStyleSheet(Stylesheet) self.init_ui() self.show_contacts() @@ -60,12 +61,16 @@ class ContactWindow(QWidget, Ui_Form): self.stackedWidget.setCurrentIndex(0) def show_contacts(self): + 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_contact) self.show_thread.start() + self.ok_flag = True def show_contact(self, contact): contact_item = ContactQListWidgetItem(contact.nickName, contact.smallHeadImgUrl, contact.smallHeadImgBLOG) diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py index 5d73691..7fc8ac4 100644 --- a/app/ui_pc/mainview.py +++ b/app/ui_pc/mainview.py @@ -85,8 +85,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % ( randint(0, 255), randint(0, 255), randint(0, 255))) self.stackedWidget.addWidget(label) - contact_window = ContactWindow() - self.stackedWidget.addWidget(contact_window) + self.contact_window = ContactWindow() + self.stackedWidget.addWidget(self.contact_window) label = QLabel('我是页面', self) label.setAlignment(Qt.AlignCenter) # 设置label的背景颜色(这里随机) @@ -99,7 +99,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.stackedWidget.setCurrentIndex(3) def setCurrentIndex(self, row): - print(row) + if row == 1: + self.contact_window.show_contacts() self.stackedWidget.setCurrentIndex(row) def about(self): From d6192132f1dfc12ff022d5408dfad897ebcded8d Mon Sep 17 00:00:00 2001 From: SiYuan <863909694@qq.com> Date: Thu, 16 Nov 2023 19:53:23 +0800 Subject: [PATCH 08/10] Create bubble_message.py --- app/components/bubble_message.py | 97 ++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 app/components/bubble_message.py diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py new file mode 100644 index 0000000..36d793b --- /dev/null +++ b/app/components/bubble_message.py @@ -0,0 +1,97 @@ +import sys + +from PyQt5.QtCore import Qt, QRectF +from PyQt5.QtGui import QImage, QPainter, QColor, QFont, QPixmap +from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy +from Lib import QtNinePatch2 + + +class Label(QLabel): + + 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') + self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) + self.adjustSize() + + def showEvent(self, event): + super(Label, self).showEvent(event) + pixmap = QtNinePatch2.createPixmapFromNinePatchImage( + self.image, self.width(), self.height()) + self.setPixmap(pixmap) + + # + 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 BubbleMessage(QWidget): + def __init__(self, text, avatar, isSend=False, parent=None): + super().__init__(parent) + self.isSend = isSend + + self.txt = text + 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) + else: + layout.addWidget(self.avatar, 0, Qt.AlignTop) + layout.addWidget(self.message) + layout.setStretch(1, 1) + 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 MainWindow(QWidget): + def __init__(self): + super().__init__() + txt = '''在工具中单击边缘可以添加黑点,单击可以删掉黑点,拖动可以调整黑点长度。勾选等选项可以查看内容、缩放等区域右侧可预览不同拉伸情况下的效果,拖动可以调整预览的拉伸比例''' + avatar = QPixmap('Data/head.jpg').scaled(60, 60) + bubble_mesage = BubbleMessage(txt, avatar, isSend=False) + layout = QVBoxLayout() + bubble_mesage1 = BubbleMessage(txt, avatar, isSend=True) + layout.addWidget(bubble_mesage) + layout.addWidget(bubble_mesage1) + # layout.setStretch(0, 1) + self.setLayout(layout) + + +app = QApplication(sys.argv) +# w = Label() +w = MainWindow() +w.resize(400, 200) +w.show() + +sys.exit(app.exec_()) From 38080499cd537372c3e1631231c4062573090d51 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Thu, 16 Nov 2023 22:39:59 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=AF=BC=E5=87=BAcsv=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 53 ++++++++++--------- app/DataBase/msg.py | 40 +++++++++++++-- app/DataBase/output_pc.py | 44 ++++++++-------- app/components/bubble_message.py | 14 +---- app/data/icons/search.svg | 1 + app/ui_pc/Icon.py | 1 + app/ui_pc/contact/contactInfo.py | 16 +++--- app/ui_pc/contact/contactUi.py | 40 +++++++++++---- app/ui_pc/contact/contactUi.ui | 79 +++++++++++++++++++---------- app/ui_pc/contact/contact_window.py | 6 ++- 10 files changed, 189 insertions(+), 105 deletions(-) create mode 100644 app/data/icons/search.svg diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f9c3bb3..5aae1dd 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,9 +5,16 @@ + + + + + + + + - diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index ea8ed4a..f08acfe 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -3,9 +3,43 @@ import sqlite3 DB = None cursor = None -misc_path = "./app/Database/Msg/MSG0.db" +msg_path = "./app/Database/Msg/MSG0.db" # misc_path = './Msg/Misc.db' -if os.path.exists(misc_path): - DB = sqlite3.connect(misc_path, check_same_thread=False) +if os.path.exists(msg_path): + DB = sqlite3.connect(msg_path, check_same_thread=False) # '''创建游标''' cursor = DB.cursor() + + +def init_database(): + global DB + global cursor + if not DB: + if os.path.exists(msg_path): + DB = sqlite3.connect(msg_path, check_same_thread=False) + # '''创建游标''' + cursor = DB.cursor() + + +def get_messages(username_): + 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 + ''' + cursor.execute(sql, [username_]) + result_ = cursor.fetchall() + return result_ + + +if __name__ == '__main__': + from pprint import pprint + + msg_path = './Msg/MSG3.db' + init_database() + + username = 'wxid_0o18ef858vnu22' + result = get_messages(username) + pprint(result) + pprint(len(result)) diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index b1bffb2..34bf547 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -1,8 +1,10 @@ import os -import numpy as np import pandas as pd -from PyQt5.QtCore import pyqtSignal +from PyQt5.QtCore import pyqtSignal, QThread + +from . import msg +from ..log import log class Output(QThread): @@ -17,32 +19,34 @@ class Output(QThread): DOCX = 1 HTML = 2 - def __init__(self, ta_u, parent=None, type_=DOCX): + def __init__(self, contact, parent=None, type_=DOCX): super().__init__(parent) self.sec = 2 # 默认1000秒 - self.ta_username = ta_u + self.contact = contact + self.ta_username = contact.wxid self.msg_id = 0 self.output_type = type_ self.total_num = 0 + self.num = 0 @log def to_csv(self, conRemark, path): - origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}" - filename = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}/{conRemark}.csv" - last_timestamp = 1601968667000 - columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"] - df = pd.DataFrame() - df["用户名"] = np.array(list(map(lambda x: x[7], messages))) - df["消息内容"] = np.array(list(map(lambda x: x[8], messages))) - df["发送时间"] = np.array(list(map(lambda x: time_format(x[6]), messages))) - df["发送状态"] = np.array(list(map(lambda x: x[3], messages))) - df["消息类型"] = np.array(list(map(lambda x: x[2], messages))) - df["isSend"] = np.array(list(map(lambda x: x[4], messages))) - df["msgId"] = np.array(list(map(lambda x: x[0], messages))) - df.to_csv(filename) - # df.to_csv('data.csv') - print(df) - self.progressSignal.emit(self.num) + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" + if not os.path.exists(origin_docx_path): + os.mkdir(origin_docx_path) + filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.csv" + # columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"] + columns = ['localId', 'TalkerId', 'Type', 'SubType', + 'IsSender', 'CreateTime', 'Status', 'StrContent', + 'StrTime'] + messages = msg.get_messages(self.contact.wxid) + # print() + df = pd.DataFrame( + data=messages, + columns=columns, + ) + df.to_csv(filename, encoding='utf-8') + self.okSignal.emit('ok') def run(self): if self.output_type == self.DOCX: diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py index 36d793b..fe3b46b 100644 --- a/app/components/bubble_message.py +++ b/app/components/bubble_message.py @@ -1,9 +1,8 @@ -import sys +from Lib import QtNinePatch2 from PyQt5.QtCore import Qt, QRectF from PyQt5.QtGui import QImage, QPainter, QColor, QFont, QPixmap -from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy -from Lib import QtNinePatch2 +from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy class Label(QLabel): @@ -86,12 +85,3 @@ class MainWindow(QWidget): layout.addWidget(bubble_mesage1) # layout.setStretch(0, 1) self.setLayout(layout) - - -app = QApplication(sys.argv) -# w = Label() -w = MainWindow() -w.resize(400, 200) -w.show() - -sys.exit(app.exec_()) diff --git a/app/data/icons/search.svg b/app/data/icons/search.svg new file mode 100644 index 0000000..076b141 --- /dev/null +++ b/app/data/icons/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/ui_pc/Icon.py b/app/ui_pc/Icon.py index 808fae3..88a0f0e 100644 --- a/app/ui_pc/Icon.py +++ b/app/ui_pc/Icon.py @@ -16,3 +16,4 @@ class Icon: Annual_Report_Icon = QIcon('./app/data/icons/annual_report.svg') Analysis_Icon = QIcon('./app/data/icons/analysis.svg') Emotion_Icon = QIcon('./app/data/icons/emotion.svg') + Search_Icon = QIcon('./app/data/icons/search.svg') diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py index 9f70d27..107977c 100644 --- a/app/ui_pc/contact/contactInfo.py +++ b/app/ui_pc/contact/contactInfo.py @@ -2,7 +2,7 @@ from PyQt5.QtCore import * from PyQt5.QtWidgets import * from app import person -from app.DataBase.output import Output +from app.DataBase.output_pc import Output from app.Ui.Icon import Icon from .contactInfoUi import Ui_Form from .userinfo import userinfo @@ -105,13 +105,13 @@ class ContactInfo(QWidget, Ui_Form): return self.outputThread = Output(self.Me, self.contact.wxid) elif self.sender() == self.toCSVAct: - QMessageBox.warning(self, - "别急别急", - "马上就实现该功能" - ) - print('开始导出csv') - return - self.outputThread = Output(self.Me, self.contact.wxid, type_=Output.CSV) + # QMessageBox.warning(self, + # "别急别急", + # "马上就实现该功能" + # ) + # print('开始导出csv') + # return + self.outputThread = Output(self.contact, type_=Output.CSV) print('导出csv') elif self.sender() == self.toHtmlAct: print('功能暂未实现') diff --git a/app/ui_pc/contact/contactUi.py b/app/ui_pc/contact/contactUi.py index aeada21..3c70aca 100644 --- a/app/ui_pc/contact/contactUi.py +++ b/app/ui_pc/contact/contactUi.py @@ -16,27 +16,47 @@ class Ui_Form(object): Form.setObjectName("Form") Form.resize(840, 752) Form.setStyleSheet("background: rgb(240, 240, 240);") - self.horizontalLayout = QtWidgets.QHBoxLayout(Form) - self.horizontalLayout.setContentsMargins(0, 0, 0, 0) - self.horizontalLayout.setObjectName("horizontalLayout") + 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(250, 30)) - self.lineEdit.setMaximumSize(QtCore.QSize(250, 16777215)) + 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);") + self.lineEdit.setCursorMoveStyle(QtCore.Qt.VisualMoveStyle) self.lineEdit.setObjectName("lineEdit") - self.verticalLayout.addWidget(self.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.addWidget(self.listWidget) - self.horizontalLayout.addLayout(self.verticalLayout) + 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.addWidget(self.stackedWidget) - self.horizontalLayout.setStretch(1, 1) + self.horizontalLayout_2.addWidget(self.stackedWidget) + self.horizontalLayout_2.setStretch(1, 1) self.retranslateUi(Form) self.stackedWidget.setCurrentIndex(-1) diff --git a/app/ui_pc/contact/contactUi.ui b/app/ui_pc/contact/contactUi.ui index b11ff70..116c90c 100644 --- a/app/ui_pc/contact/contactUi.ui +++ b/app/ui_pc/contact/contactUi.ui @@ -16,36 +16,59 @@ background: rgb(240, 240, 240); - - - 0 - - - 0 - - - 0 - - - 0 - + - + + + 0 + - - - - 250 - 30 - - - - - 250 - 16777215 - - - + + + + + + + + + + + + + + + 200 + 30 + + + + + 200 + 16777215 + + + + background:transparent; + border-width:0; + border-style:outset; + background-color:rgb(226,226,226); + + + + Qt::VisualMoveStyle + + + + + + + + + + + + + diff --git a/app/ui_pc/contact/contact_window.py b/app/ui_pc/contact/contact_window.py index 4a0ea48..1496928 100644 --- a/app/ui_pc/contact/contact_window.py +++ b/app/ui_pc/contact/contact_window.py @@ -1,11 +1,12 @@ from PyQt5.QtCore import QThread, pyqtSignal -from PyQt5.QtWidgets import QWidget, QMessageBox +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 .contactInfo import ContactInfo from .contactUi import Ui_Form +from ..Icon import Icon # 美化样式表 Stylesheet = """ @@ -55,6 +56,9 @@ class ContactWindow(QWidget, Ui_Form): 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.listWidget.clear() self.listWidget.currentRowChanged.connect(self.setCurrentIndex) self.listWidget.setCurrentRow(0) From 9c7cb674f8f99ff5fd05ce1aeb10dc3298aeae24 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Thu, 16 Nov 2023 23:16:38 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9A=84=E8=81=8A=E5=A4=A9=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 76 ++++++++++++++++++--------------------- app/DataBase/micro_msg.py | 6 ++++ app/DataBase/msg.py | 56 +++++++++++++++++++++-------- app/ui_pc/mainview.py | 7 ++++ 4 files changed, 89 insertions(+), 56 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 5aae1dd..066ce8f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,17 +4,11 @@ - @@ -663,7 +656,8 @@ - diff --git a/app/DataBase/micro_msg.py b/app/DataBase/micro_msg.py index f437fad..2abfa61 100644 --- a/app/DataBase/micro_msg.py +++ b/app/DataBase/micro_msg.py @@ -37,5 +37,11 @@ def get_contact(): return result +def close(): + global DB + if DB: + DB.close() + + if __name__ == '__main__': get_contact() diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index f08acfe..6aa9b6b 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -1,24 +1,40 @@ import os.path +import re import sqlite3 -DB = None -cursor = None -msg_path = "./app/Database/Msg/MSG0.db" +DB = [] +cursor = [] +msg_root_path = "./app/Database/Msg/" # misc_path = './Msg/Misc.db' -if os.path.exists(msg_path): - DB = sqlite3.connect(msg_path, check_same_thread=False) - # '''创建游标''' - cursor = DB.cursor() +if os.path.exists(msg_root_path): + for root, dirs, files in os.walk(msg_root_path): + for file in files: + if re.match('^MSG[0-9]+\.db$', file): + # print('ok', file) + msg_path = os.path.join(msg_root_path, file) + DB0 = sqlite3.connect(msg_path, check_same_thread=False) + # '''创建游标''' + cursor0 = DB0.cursor() + DB.append(DB0) + cursor.append(cursor0) def init_database(): global DB global cursor if not DB: - if os.path.exists(msg_path): - DB = sqlite3.connect(msg_path, check_same_thread=False) - # '''创建游标''' - cursor = DB.cursor() + if os.path.exists(msg_root_path): + for root, dirs, files in os.walk(msg_root_path): + for file in files: + # print(file) + if re.match('^MSG[0-9]+\.db$', file): + print('ok', file) + msg_path = os.path.join(msg_root_path, file) + DB0 = sqlite3.connect(msg_path, check_same_thread=False) + # '''创建游标''' + cursor0 = DB0.cursor() + DB.append(DB0) + cursor.append(cursor0) def get_messages(username_): @@ -28,15 +44,25 @@ def get_messages(username_): where StrTalker=? order by CreateTime ''' - cursor.execute(sql, [username_]) - result_ = cursor.fetchall() - return result_ + result = [] + for cur in cursor: + cur.execute(sql, [username_]) + result_ = cur.fetchall() + # print(len(result)) + result += result_ + 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_path = './Msg/MSG3.db' + msg_root_path = './Msg/' init_database() username = 'wxid_0o18ef858vnu22' diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py index 7fc8ac4..0b051e7 100644 --- a/app/ui_pc/mainview.py +++ b/app/ui_pc/mainview.py @@ -13,6 +13,7 @@ from PyQt5.QtCore import * from PyQt5.QtWidgets import * from app import config +from app.DataBase import msg from app.Ui.Icon import Icon from . import mainwindow from .contact import ContactWindow @@ -112,3 +113,9 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): f"QQ交流群:{config.contact}\n" "地址:https://github.com/LC044/WeChatMsg" ) + + def close(self) -> bool: + del self.listWidget + del self.stackedWidget + msg.close() + self.contact_window.close()