diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index 6d19734..1deb06c 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -1,6 +1,7 @@ import csv import os import traceback +from typing import List from PyQt5.QtCore import pyqtSignal, QThread from PyQt5.QtWidgets import QFileDialog @@ -27,6 +28,8 @@ class Output(QThread): progressSignal = pyqtSignal(int) rangeSignal = pyqtSignal(int) okSignal = pyqtSignal(int) + batchOkSignal = pyqtSignal(int) + nowContact = pyqtSignal(str) i = 1 CSV = 0 DOCX = 1 @@ -34,17 +37,18 @@ class Output(QThread): CSV_ALL = 3 CONTACT_CSV = 4 TXT = 5 + Batch = 10086 - def __init__(self, contact, type_=DOCX, message_types={}, parent=None): + def __init__(self, contact, type_=DOCX, message_types={}, sub_type=[], parent=None): super().__init__(parent) - self.Child0 = None + self.children = [] self.last_timestamp = 0 + self.sub_type = sub_type self.message_types = message_types self.sec = 2 # 默认1000秒 self.contact = contact - self.ta_username = contact.wxid if contact else '' self.msg_id = 0 - self.output_type = type_ + self.output_type: int | List[int] = type_ self.total_num = 1 self.num = 0 @@ -123,60 +127,115 @@ class Output(QThread): gender = '男' else: gender = '女' - writer.writerow([*contact[:9], contact[10], gender,detail.get('telephone'),detail.get('signature'),*detail.get('region')]) + writer.writerow([*contact[:9], contact[10], gender, detail.get('telephone'), detail.get('signature'), + *detail.get('region')]) self.okSignal.emit(1) + def batch_export(self): + print('开始批量导出') + print(self.sub_type, self.message_types) + print(len(self.contact)) + print([contact.remark for contact in self.contact]) + self.batch_num_total = len(self.contact)*len(self.sub_type) + self.batch_num = 0 + self.rangeSignal.emit(self.batch_num_total) + for contact in self.contact: + # print('联系人', contact.remark) + for type_ in self.sub_type: + # print('导出类型', type_) + if type_ == self.DOCX: + self.to_docx(contact, self.message_types,True) + elif type_ == self.TXT: + # print('批量导出txt') + self.to_txt(contact, self.message_types,True) + elif type_ == self.CSV: + self.to_csv(contact, self.message_types,True) + elif type_ == self.HTML: + self.to_html(contact, self.message_types,True) + + def batch_finish_one(self, num): + self.nowContact.emit(self.contact[self.batch_num//len(self.sub_type)].remark) + self.batch_num += 1 + if self.batch_num == self.batch_num_total: + self.okSignal.emit(1) + + def to_docx(self, contact, message_types, is_batch=False): + Child = DocxExporter(contact, type_=self.DOCX, message_types=message_types) + self.children.append(Child) + Child.progressSignal.connect(self.progress) + if not is_batch: + Child.rangeSignal.connect(self.rangeSignal) + Child.okSignal.connect(self.okSignal if not is_batch else self.batch_finish_one) + Child.start() + + def to_txt(self, contact, message_types, is_batch=False): + Child = TxtExporter(contact, type_=self.TXT, message_types=message_types) + self.children.append(Child) + Child.progressSignal.connect(self.progress) + if not is_batch: + Child.rangeSignal.connect(self.rangeSignal) + Child.okSignal.connect(self.okSignal if not is_batch else self.batch_finish_one) + Child.start() + + def to_html(self, contact, message_types, is_batch=False): + Child = HtmlExporter(contact, type_=self.output_type, message_types=message_types) + self.children.append(Child) + Child.progressSignal.connect(self.progress) + if not is_batch: + Child.rangeSignal.connect(self.rangeSignal) + Child.okSignal.connect(self.count_finish_num) + Child.start() + self.total_num = 1 + if message_types.get(34): + # 语音消息单独的线程 + self.total_num += 1 + output_media = OutputMedia(contact) + self.children.append(output_media) + output_media.okSingal.connect(self.count_finish_num) + output_media.progressSignal.connect(self.progressSignal) + output_media.start() + if message_types.get(47): + # emoji消息单独的线程 + self.total_num += 1 + output_emoji = OutputEmoji(contact) + self.children.append(output_emoji) + output_emoji.okSingal.connect(self.count_finish_num) + output_emoji.progressSignal.connect(self.progressSignal) + output_emoji.start() + if message_types.get(3): + # 图片消息单独的线程 + self.total_num += 1 + output_image = OutputImage(contact) + self.children.append(output_image) + output_image.okSingal.connect(self.count_finish_num) + output_image.progressSignal.connect(self.progressSignal) + output_image.start() + + def to_csv(self, contact, message_types, is_batch=False): + Child = CSVExporter(contact, type_=self.CSV, message_types=message_types) + self.children.append(Child) + Child.progressSignal.connect(self.progress) + if not is_batch: + Child.rangeSignal.connect(self.rangeSignal) + Child.okSignal.connect(self.okSignal if not is_batch else self.batch_finish_one) + Child.start() + def run(self): if self.output_type == self.DOCX: - self.Child = DocxExporter(self.contact, type_=self.output_type, message_types=self.message_types) - self.Child.progressSignal.connect(self.progress) - self.Child.rangeSignal.connect(self.rangeSignal) - self.Child.okSignal.connect(self.okSignal) - self.Child.start() + self.to_docx(self.contact, self.message_types) elif self.output_type == self.CSV_ALL: self.to_csv_all() elif self.output_type == self.CONTACT_CSV: self.contact_to_csv() elif self.output_type == self.TXT: - self.Child = TxtExporter(self.contact, type_=self.output_type, message_types=self.message_types) - self.Child.progressSignal.connect(self.progress) - self.Child.rangeSignal.connect(self.rangeSignal) - self.Child.okSignal.connect(self.okSignal) - self.Child.start() + self.to_txt(self.contact, self.message_types) elif self.output_type == self.CSV: - self.Child = CSVExporter(self.contact, type_=self.output_type, message_types=self.message_types) - self.Child.progressSignal.connect(self.progress) - self.Child.rangeSignal.connect(self.rangeSignal) - self.Child.okSignal.connect(self.okSignal) - self.Child.start() + self.to_csv(self.contact, self.message_types) elif self.output_type == self.HTML: - self.Child = HtmlExporter(self.contact, type_=self.output_type, message_types=self.message_types) - self.Child.progressSignal.connect(self.progress) - self.Child.rangeSignal.connect(self.rangeSignal) - self.Child.okSignal.connect(self.count_finish_num) - self.Child.start() - if self.message_types.get(34): - # 语音消息单独的线程 - self.total_num += 1 - self.output_media = OutputMedia(self.contact) - self.output_media.okSingal.connect(self.count_finish_num) - self.output_media.progressSignal.connect(self.progressSignal) - self.output_media.start() - if self.message_types.get(47): - # emoji消息单独的线程 - self.total_num += 1 - self.output_emoji = OutputEmoji(self.contact) - self.output_emoji.okSingal.connect(self.count_finish_num) - self.output_emoji.progressSignal.connect(self.progressSignal) - self.output_emoji.start() - if self.message_types.get(3): - # 图片消息单独的线程 - self.total_num += 1 - self.output_image = OutputImage(self.contact) - self.output_image.okSingal.connect(self.count_finish_num) - self.output_image.progressSignal.connect(self.progressSignal) - self.output_image.start() + self.to_html(self.contact, self.message_types) + elif self.output_type == self.Batch: + self.batch_export() def count_finish_num(self, num): """ @@ -187,7 +246,11 @@ class Output(QThread): self.num += 1 if self.num == self.total_num: # 所有子线程都完成之后就发送完成信号 - self.okSignal.emit(1) + if self.output_type == self.Batch: + self.batch_finish_one(1) + else: + self.okSignal.emit(1) + self.num = 0 def cancel(self): self.requestInterruption() diff --git a/app/components/Button_Contact.py b/app/components/Button_Contact.py index 14d5b0b..8486d5a 100644 --- a/app/components/Button_Contact.py +++ b/app/components/Button_Contact.py @@ -3,7 +3,6 @@ from datetime import datetime from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5.QtCore import * -import app.DataBase.data as data from app import person diff --git a/app/components/export_contact_item.py b/app/components/export_contact_item.py new file mode 100644 index 0000000..4816c90 --- /dev/null +++ b/app/components/export_contact_item.py @@ -0,0 +1,120 @@ +import sys + +from PyQt5.Qt import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * + +try: + from .CAvatar import CAvatar +except: + from CAvatar import CAvatar + +Stylesheet = """ +QWidget{ + background: rgb(238,244,249); +} +""" +Stylesheet_hover = """ +QWidget,QLabel{ + background: rgb(230, 235, 240); +} +""" +Stylesheet_clicked = """ +QWidget,QLabel{ + background: rgb(230, 235, 240); +} +""" + + +class QListWidgetItemWidget(QWidget): + def __init__(self): + super().__init__() + self.is_selected = False + + def leaveEvent(self, e): # 鼠标离开label + if self.is_selected: + return + self.setStyleSheet(Stylesheet) + + def enterEvent(self, e): # 鼠标移入label + self.setStyleSheet(Stylesheet_hover) + + +# 自定义的item 继承自QListWidgetItem +class ContactQListWidgetItem(QListWidgetItem): + def __init__(self, name, url, img_bytes=None): + super().__init__() + self.is_select = False + # 自定义item中的widget 用来显示自定义的内容 + self.widget = QListWidgetItemWidget() + # 用来显示name + self.nameLabel = QLabel(self.widget) + self.nameLabel.setText(name) + # 用来显示avator(图像) + self.avatorLabel = CAvatar(parent=self.widget, shape=CAvatar.Rectangle, size=QSize(30, 30), + url=url, img_bytes=img_bytes) + # 设置布局用来对nameLabel和avatorLabel进行布局 + hbox = QHBoxLayout() + self.checkBox = QCheckBox() + hbox.addWidget(self.checkBox) + hbox.addWidget(self.avatorLabel) + hbox.addWidget(self.nameLabel) + hbox.addStretch(1) + # 设置widget的布局 + self.widget.setLayout(hbox) + self.widget.setStyleSheet(Stylesheet) + # 设置自定义的QListWidgetItem的sizeHint,不然无法显示 + self.setSizeHint(self.widget.sizeHint()) + + def select(self): + """ + 设置选择后的事件 + @return: + """ + self.widget.is_selected = True + self.is_select = not self.is_select + # print('选择',self.is_select) + self.checkBox.setChecked(self.is_select) + # self.widget.setStyleSheet(Stylesheet_clicked) + def force_select(self): + self.is_select = True + self.checkBox.setChecked(self.is_select) + + def force_dis_select(self): + self.is_select = False + self.checkBox.setChecked(self.is_select) + + def dis_select(self): + """ + 设置取消选择的事件 + @return: + """ + self.widget.is_selected = False + self.widget.setStyleSheet(Stylesheet) + + +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: item.select()) + + w.show() + sys.exit(app.exec_()) diff --git a/app/person.py b/app/person.py index 9cb416e..6e0a9a9 100644 --- a/app/person.py +++ b/app/person.py @@ -74,7 +74,7 @@ class Contact(Person): self.nickName = contact_info.get('NickName') if not self.remark: self.remark = self.nickName - self.remark = re.sub(r'[\/:*?"<>|\s]', '_', self.remark) + self.remark = re.sub(r'[\/:*?"<>|\s\.]', '_', self.remark) self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl') self.smallHeadImgBLOG = b'' self.avatar = QPixmap() diff --git a/app/ui/mainview.py b/app/ui/mainview.py index 4ea7814..7c620c8 100644 --- a/app/ui/mainview.py +++ b/app/ui/mainview.py @@ -20,6 +20,7 @@ from . import mainwindow from app.ui.menu.about_dialog import AboutDialog from .chat import ChatWindow from .contact import ContactWindow +from .menu.export import ExportDialog from .tool.tool_window import ToolWindow from ..DataBase.output_pc import Output from ..components.QCursorGif import QCursorGif @@ -126,6 +127,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow,QCursorGif): self.action_output_CSV.triggered.connect(self.output) self.action_output_contacts.setIcon(Icon.Output) self.action_output_contacts.triggered.connect(self.output) + self.action_batch_export.setIcon(Icon.Output) + self.action_batch_export.triggered.connect(self.output) self.action_desc.setIcon(Icon.Help_Icon) self.action_help_contact.triggered.connect( lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/5"))) @@ -231,6 +234,9 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow,QCursorGif): self.outputThread.okSignal.connect( lambda x: self.message('联系人导出成功')) self.outputThread.start() + elif self.sender() == self.action_batch_export: + dialog = ExportDialog(None, title='批量导出聊天记录', parent=self) + result = dialog.exec_() # 使用exec_()获取用户的操作结果 def message(self, msg): self.stopBusy() diff --git a/app/ui/mainwindow.py b/app/ui/mainwindow.py index 54a0838..9e11e68 100644 --- a/app/ui/mainwindow.py +++ b/app/ui/mainwindow.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'mainwindow.ui' # -# Created by: PyQt5 UI code generator 5.15.7 +# Created by: PyQt5 UI code generator 5.15.10 # # 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. @@ -94,8 +94,6 @@ class Ui_MainWindow(object): self.menu_2.setObjectName("menu_2") self.menu_about = QtWidgets.QMenu(self.menubar) self.menu_about.setObjectName("menu_about") - self.menu_3 = QtWidgets.QMenu(self.menubar) - self.menu_3.setObjectName("menu_3") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) font = QtGui.QFont() @@ -125,6 +123,8 @@ class Ui_MainWindow(object): self.action_output_CSV.setObjectName("action_output_CSV") self.action_output_contacts = QtWidgets.QAction(MainWindow) self.action_output_contacts.setObjectName("action_output_contacts") + self.action_batch_export = QtWidgets.QAction(MainWindow) + self.action_batch_export.setObjectName("action_batch_export") self.menu_F.addSeparator() self.menu_F.addSeparator() self.menu_F.addAction(self.action_3) @@ -132,6 +132,7 @@ class Ui_MainWindow(object): self.menu_output.addAction(self.action_output_CSV) self.menu_data.addAction(self.menu_output.menuAction()) self.menu_data.addAction(self.action_output_contacts) + self.menu_data.addAction(self.action_batch_export) self.menu_2.addAction(self.action_help_decrypt) self.menu_2.addAction(self.action_help_chat) self.menu_2.addAction(self.action_help_contact) @@ -140,7 +141,6 @@ class Ui_MainWindow(object): self.menubar.addAction(self.menu_data.menuAction()) self.menubar.addAction(self.menu_2.menuAction()) self.menubar.addAction(self.menu_about.menuAction()) - self.menubar.addAction(self.menu_3.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -167,7 +167,6 @@ class Ui_MainWindow(object): self.menu_output.setTitle(_translate("MainWindow", "导出聊天记录(全部)")) self.menu_2.setTitle(_translate("MainWindow", "帮助")) self.menu_about.setTitle(_translate("MainWindow", "关于")) - self.menu_3.setTitle(_translate("MainWindow", "不显示或者显示异常请重启应用、没反应那就多等一会儿")) self.action_3.setText(_translate("MainWindow", "保存")) self.action_4.setText(_translate("MainWindow", "退出")) self.action_help_decrypt.setText(_translate("MainWindow", "解密教程")) @@ -176,3 +175,4 @@ class Ui_MainWindow(object): self.action_help_contact.setText(_translate("MainWindow", "好友相关")) self.action_output_CSV.setText(_translate("MainWindow", "CSV")) self.action_output_contacts.setText(_translate("MainWindow", "导出联系人")) + self.action_batch_export.setText(_translate("MainWindow", "批量导出")) diff --git a/app/ui/menu/export.py b/app/ui/menu/export.py new file mode 100644 index 0000000..6798fdd --- /dev/null +++ b/app/ui/menu/export.py @@ -0,0 +1,233 @@ +import time +from typing import List + +from PyQt5 import QtWidgets +from PyQt5.QtCore import QTimer, QThread, pyqtSignal +from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \ + QProgressBar, QLabel, QMessageBox + +from app.DataBase import micro_msg_db, misc_db +from app.DataBase.output_pc import Output +from app.components import ScrollBar +from app.components.export_contact_item import ContactQListWidgetItem +from app.person import Contact +from app.ui.menu.exportUi import Ui_Dialog + +types = { + '文本': 1, + '图片': 3, + '语音': 34, + '视频': 43, + '表情包': 47, + '音乐与音频': 4903, + '文件': 4906, + '分享卡片': 4905, + '拍一拍等系统消息': 10000 +} +file_format = { + 'Docx': Output.DOCX, + 'TXT': Output.TXT, + 'HTML': Output.HTML, + 'CSV': Output.CSV, +} +Stylesheet = """ +QPushButton{ + background-color: #ffffff; +} +QPushButton:hover { + background-color: lightgray; +} +""" + + +class ExportDialog(QDialog, Ui_Dialog): + def __init__(self, contact=None, title="选择导出的类型", file_type="html", parent=None): + super(ExportDialog, self).__init__(parent) + self.setupUi(self) + self.contacts: List[Contact] = [] + self.setStyleSheet(Stylesheet) + self.contact = contact + self.btn_select_all.clicked.connect(self.select_all) + self.select_all_flag = False + self.btn_start.clicked.connect(self.export_data) + self.comboBox_time.activated.connect(self.set_export_date) + self.export_choices = {"文本": True, "图片": True, "语音": False, "视频": False, "表情包": False, + '音乐与音频': False, '分享卡片': False, '文件': False, + '拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择 + self.setWindowTitle(title) + self.resize(800, 600) + self.worker = None # 导出线程 + for export_type, default_state in self.export_choices.items(): + checkbox = QCheckBox(export_type) + checkbox.setObjectName('message_type') + checkbox.setChecked(default_state) + self.verticalLayout_2.addWidget(checkbox) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + self.timer = QTimer(self) + self.time = 0 + self.total_msg_num = 99999 # 总的消息个数 + self.num = 0 # 当前完成的消息个数 + self.timer.timeout.connect(self.update_elapsed_time) + self.show_thread = ShowContactThread() + self.show_thread.showSingal.connect(self.show_contact) + # self.show_thread.load_finish_signal.connect(self.stop_loading) + self.show_thread.start() + self.listWidget.setVerticalScrollBar(ScrollBar()) + # self.listWidget.currentRowChanged.connect(self.setCurrentIndex) + self.listWidget.itemClicked.connect(self.setCurrentIndex) + self.visited = set() + self.now_index = 0 + + def set_export_date(self): + date_range = self.comboBox_time.currentText() + if date_range == '全部时间': + pass + elif date_range == '最近三个月': + QMessageBox.warning(self, + "别急别急", + "马上就实现该功能" + ) + elif date_range == '自定义时间': + QMessageBox.warning(self, + "别急别急", + "马上就实现该功能" + ) + + def export_data(self): + self.btn_start.setEnabled(False) + # 在这里获取用户选择的导出数据类型 + selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in + zip(self.export_choices.keys(), self.findChildren(QCheckBox, 'message_type'))} + + # 在这里根据用户选择的数据类型执行导出操作 + print("选择的数据类型:", selected_types) + + file_types = [] + for checkbox in [self.checkBox_txt, self.checkBox_csv, self.checkBox_html, self.checkBox_word]: + if checkbox.isChecked(): + file_types.append(file_format[checkbox.text()]) + select_contacts = [] + count = self.listWidget.count() + # 遍历listwidget中的内容 + for i in range(count): + item = self.listWidget.item(i) + if item.is_select: + select_contacts.append(self.contacts[i]) + # 在这里根据用户选择的数据类型执行导出操作 + print("选择的文件格式:", file_types) + self.worker = Output(select_contacts, type_=Output.Batch, message_types=selected_types, sub_type=file_types) + # self.worker.progressSignal.connect(self.update_progress) + self.worker.okSignal.connect(self.export_finished) + self.worker.rangeSignal.connect(self.set_total_msg_num) + self.worker.nowContact.connect(self.update_progress) + self.worker.start() + # 启动定时器,每1000毫秒更新一次任务进度 + self.timer.start(1000) + self.start_time = time.time() + # self.accept() # 使用accept关闭对话框 + # 绑定点击槽函数 点击显示对应item中的name + + def set_total_msg_num(self, num): + self.total_msg_num = num + # b''+num +(1,1) + + def setCurrentIndex(self, item): + # print(row) + # row = self.listWidget.it + # item = self.listWidget.item(row) + item.select() + item.dis_select() + # self.now_index = row + + def select_all(self): + self.select_all_flag = not self.select_all_flag + print('全选', self.select_all_flag) + if self.select_all_flag: + count = self.listWidget.count() + # 遍历listwidget中的内容 + for i in range(count): + item = self.listWidget.item(i) + item.force_select() + self.btn_select_all.setText('全不选') + else: + count = self.listWidget.count() + # 遍历listwidget中的内容 + for i in range(count): + item = self.listWidget.item(i) + item.force_dis_select() + self.btn_select_all.setText('全选') + + def export_finished(self): + self.btn_start.setEnabled(True) + self.time = 0 + end_time = time.time() + print(f'总耗时:{end_time - self.start_time}s') + reply = QMessageBox(self) + reply.setIcon(QMessageBox.Information) + reply.setWindowTitle('OK') + reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)") + reply.addButton("确认", QMessageBox.AcceptRole) + reply.addButton("取消", QMessageBox.RejectRole) + api = reply.exec_() + self.accept() + + def show_contact(self, contact): + # return + # print(contact.remark) + contact_item = ContactQListWidgetItem(contact.remark, contact.smallHeadImgUrl, contact.smallHeadImgBLOG) + self.listWidget.addItem(contact_item) + self.listWidget.setItemWidget(contact_item, contact_item.widget) + self.contacts.append(contact) + + def update_elapsed_time(self): + self.time += 1 + self.label_time.setText(f"耗时: {self.time}s") + + def update_progress(self, remark): + self.num += 1 + progress_percentage = int((self.num) / self.total_msg_num * 100) + self.progressBar.setValue(progress_percentage) + self.label_process.setText(f"导出进度: {progress_percentage}% {remark}") + + +class ShowContactThread(QThread): + showSingal = pyqtSignal(Contact) + load_finish_signal = pyqtSignal(bool) + + # heightSingal = pyqtSignal(int) + def __init__(self): + super().__init__() + + def run(self) -> None: + contact_info_lists = micro_msg_db.get_contact() + for contact_info_list in contact_info_lists: + # UserName, Alias,Type,Remark,NickName,PYInitial,RemarkPYInitial,ContactHeadImgUrl.smallHeadImgUrl,ContactHeadImgUrl,bigHeadImgUrl + contact_info = { + 'UserName': contact_info_list[0], + 'Alias': contact_info_list[1], + 'Type': contact_info_list[2], + 'Remark': contact_info_list[3], + 'NickName': contact_info_list[4], + 'smallHeadImgUrl': contact_info_list[7] + } + contact = Contact(contact_info) + contact.smallHeadImgBLOG = misc_db.get_avatar_buffer(contact.wxid) + contact.set_avatar(contact.smallHeadImgBLOG) + self.showSingal.emit(contact) + # print(contact.wxid) + # pprint(contact.__dict__) + self.load_finish_signal.emit(True) + + +if __name__ == '__main__': + import sys + + app = QApplication(sys.argv) + dialog = ExportDialog() + result = dialog.exec_() # 使用exec_()获取用户的操作结果 + if result == QDialog.Accepted: + print("用户点击了导出按钮") + else: + print("用户点击了取消按钮") + sys.exit(app.exec_()) diff --git a/app/ui/menu/exportUi.py b/app/ui/menu/exportUi.py new file mode 100644 index 0000000..d2a8a2c --- /dev/null +++ b/app/ui/menu/exportUi.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'exportUi.ui' +# +# Created by: PyQt5 UI code generator 5.15.10 +# +# 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(553, 394) + self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.label_3 = QtWidgets.QLabel(Dialog) + self.label_3.setObjectName("label_3") + self.horizontalLayout.addWidget(self.label_3) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.btn_select_all = QtWidgets.QPushButton(Dialog) + self.btn_select_all.setObjectName("btn_select_all") + self.horizontalLayout.addWidget(self.btn_select_all) + self.comboBox_time = QtWidgets.QComboBox(Dialog) + self.comboBox_time.setObjectName("comboBox_time") + self.comboBox_time.addItem("") + self.comboBox_time.addItem("") + self.comboBox_time.addItem("") + self.horizontalLayout.addWidget(self.comboBox_time) + self.comboBox_type = QtWidgets.QComboBox(Dialog) + self.comboBox_type.setObjectName("comboBox_type") + self.comboBox_type.addItem("") + self.comboBox_type.addItem("") + self.horizontalLayout.addWidget(self.comboBox_type) + self.verticalLayout_3.addLayout(self.horizontalLayout) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtWidgets.QLabel(Dialog) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.checkBox_word = QtWidgets.QCheckBox(Dialog) + self.checkBox_word.setObjectName("checkBox_word") + self.verticalLayout.addWidget(self.checkBox_word) + self.checkBox_html = QtWidgets.QCheckBox(Dialog) + self.checkBox_html.setObjectName("checkBox_html") + self.verticalLayout.addWidget(self.checkBox_html) + self.checkBox_csv = QtWidgets.QCheckBox(Dialog) + self.checkBox_csv.setObjectName("checkBox_csv") + self.verticalLayout.addWidget(self.checkBox_csv) + self.checkBox_txt = QtWidgets.QCheckBox(Dialog) + self.checkBox_txt.setChecked(True) + self.checkBox_txt.setObjectName("checkBox_txt") + self.verticalLayout.addWidget(self.checkBox_txt) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem1) + self.horizontalLayout_2.addLayout(self.verticalLayout) + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.label_2 = QtWidgets.QLabel(Dialog) + self.label_2.setObjectName("label_2") + self.verticalLayout_2.addWidget(self.label_2) + self.horizontalLayout_2.addLayout(self.verticalLayout_2) + self.listWidget = QtWidgets.QListWidget(Dialog) + self.listWidget.setObjectName("listWidget") + self.horizontalLayout_2.addWidget(self.listWidget) + self.horizontalLayout_2.setStretch(0, 1) + self.horizontalLayout_2.setStretch(1, 1) + self.horizontalLayout_2.setStretch(2, 5) + self.verticalLayout_3.addLayout(self.horizontalLayout_2) + self.progressBar = QtWidgets.QProgressBar(Dialog) + self.progressBar.setProperty("value", 24) + self.progressBar.setObjectName("progressBar") + self.verticalLayout_3.addWidget(self.progressBar) + self.label_process = QtWidgets.QLabel(Dialog) + self.label_process.setText("") + self.label_process.setObjectName("label_process") + self.verticalLayout_3.addWidget(self.label_process) + self.label_time = QtWidgets.QLabel(Dialog) + self.label_time.setText("") + self.label_time.setObjectName("label_time") + self.verticalLayout_3.addWidget(self.label_time) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem2) + self.btn_start = QtWidgets.QPushButton(Dialog) + self.btn_start.setObjectName("btn_start") + self.horizontalLayout_3.addWidget(self.btn_start) + self.verticalLayout_3.addLayout(self.horizontalLayout_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_select_all.setText(_translate("Dialog", "全选")) + self.comboBox_time.setItemText(0, _translate("Dialog", "全部时间")) + self.comboBox_time.setItemText(1, _translate("Dialog", "最近三个月")) + self.comboBox_time.setItemText(2, _translate("Dialog", "自定义时间")) + self.comboBox_type.setItemText(0, _translate("Dialog", "全部聊天记录")) + self.comboBox_type.setItemText(1, _translate("Dialog", "不含图片/视频/文件")) + self.label.setText(_translate("Dialog", "导出格式")) + self.checkBox_word.setText(_translate("Dialog", "Docx")) + self.checkBox_html.setText(_translate("Dialog", "HTML")) + self.checkBox_csv.setText(_translate("Dialog", "CSV")) + self.checkBox_txt.setText(_translate("Dialog", "TXT")) + self.label_2.setText(_translate("Dialog", "消息类型")) + self.btn_start.setText(_translate("Dialog", "开始")) diff --git a/readme.md b/readme.md index 248535e..ccb26bc 100644 --- a/readme.md +++ b/readme.md @@ -67,6 +67,7 @@ - 个人年度报告 - 群组年度报告 - 按日期、关键词索引 + - 支持企业微信好友 - 小伙伴们想要其他功能可以留言哦📬 - 🔥项目正处于并将长期处于发展阶段,给我一些时间♾️,你所期望的未来都会实现(养成系开发者),可关注文末公众号持续获取项目更新动态