init
This commit is contained in:
0
app/ui/menu/__init__.py
Normal file
0
app/ui/menu/__init__.py
Normal file
BIN
app/ui/menu/about_dialog.cp310-win_amd64.pyd
Normal file
BIN
app/ui/menu/about_dialog.cp310-win_amd64.pyd
Normal file
Binary file not shown.
BIN
app/ui/menu/about_dialog.cp311-win_amd64.pyd
Normal file
BIN
app/ui/menu/about_dialog.cp311-win_amd64.pyd
Normal file
Binary file not shown.
BIN
app/ui/menu/about_dialog.cp312-win_amd64.pyd
Normal file
BIN
app/ui/menu/about_dialog.cp312-win_amd64.pyd
Normal file
Binary file not shown.
61
app/ui/menu/dialog.py
Normal file
61
app/ui/menu/dialog.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'dialog.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(553, 394)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label_version = QtWidgets.QLabel(Dialog)
|
||||
self.label_version.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.label_version.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_version.setObjectName("label_version")
|
||||
self.verticalLayout.addWidget(self.label_version)
|
||||
self.label_logo = QtWidgets.QLabel(Dialog)
|
||||
self.label_logo.setMinimumSize(QtCore.QSize(100, 100))
|
||||
self.label_logo.setObjectName("label_logo")
|
||||
self.verticalLayout.addWidget(self.label_logo)
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.horizontalLayout.addLayout(self.verticalLayout)
|
||||
self.textBrowser = QtWidgets.QTextBrowser(Dialog)
|
||||
self.textBrowser.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||
self.textBrowser.setObjectName("textBrowser")
|
||||
self.horizontalLayout.addWidget(self.textBrowser)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout)
|
||||
self.label_weixin = QtWidgets.QLabel(Dialog)
|
||||
self.label_weixin.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_weixin.setObjectName("label_weixin")
|
||||
self.verticalLayout_2.addWidget(self.label_weixin)
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.verticalLayout_2.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(Dialog)
|
||||
self.buttonBox.accepted.connect(Dialog.accept) # type: ignore
|
||||
self.buttonBox.rejected.connect(Dialog.reject) # type: ignore
|
||||
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||
|
||||
def retranslateUi(self, Dialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
||||
self.label_version.setText(_translate("Dialog", "TextLabel"))
|
||||
self.label_logo.setText(_translate("Dialog", "logo"))
|
||||
self.label_weixin.setText(_translate("Dialog", "TextLabel"))
|
||||
288
app/ui/menu/export.py
Normal file
288
app/ui/menu/export.py
Normal file
@@ -0,0 +1,288 @@
|
||||
import os
|
||||
import sys as sys_
|
||||
import time
|
||||
from typing import List
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, QObject
|
||||
from PyQt5.QtGui import QTextCursor
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox
|
||||
|
||||
from app.DataBase import micro_msg_db, misc_db
|
||||
from app.util.exporter.output import Output
|
||||
from app.components import ScrollBar
|
||||
from app.components.export_contact_item import ContactQListWidgetItem
|
||||
from app.config import OUTPUT_DIR
|
||||
from app.person import Contact
|
||||
from app.ui.menu.exportUi import Ui_Dialog
|
||||
from app.ui.menu.export_time_range import TimeRangeDialog
|
||||
|
||||
types = {
|
||||
'文本': 1,
|
||||
'图片': 3,
|
||||
'语音': 34,
|
||||
'视频': 43,
|
||||
'表情包': 47,
|
||||
'音乐与音频': 4903,
|
||||
'文件': 4906,
|
||||
'分享卡片': 4905,
|
||||
'转账': 492000,
|
||||
'音视频通话': 50,
|
||||
'拍一拍等系统消息': 10000,
|
||||
}
|
||||
file_format = {
|
||||
'Docx': Output.DOCX,
|
||||
'TXT': Output.TXT,
|
||||
'HTML': Output.HTML,
|
||||
'CSV': Output.CSV,
|
||||
'JSON': Output.JSON,
|
||||
}
|
||||
Stylesheet = """
|
||||
"""
|
||||
|
||||
|
||||
class EmittingStr(QObject):
|
||||
textWritten = pyqtSignal(str) # 定义一个发送str的信号
|
||||
|
||||
def write(self, text):
|
||||
self.textWritten.emit(str(text))
|
||||
|
||||
|
||||
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)
|
||||
# 下面将输出重定向到textBrowser中
|
||||
sys_.stdout = EmittingStr(textWritten=self.outputWritten)
|
||||
# sys.stderr = EmittingStr(textWritten=self.outputWritten)
|
||||
scroll_bar = ScrollBar()
|
||||
self.textBrowser.setVerticalScrollBar(scroll_bar)
|
||||
self.export_choices = {"文本": True, "图片": True, "语音": False, "视频": False, "表情包": False,
|
||||
'音乐与音频': False, '分享卡片': False, '文件': False,
|
||||
'转账': False, '音视频通话': False,'拍一拍等系统消息': True} # 定义导出的数据类型
|
||||
self.setWindowTitle(title)
|
||||
self.checkBox_word.setEnabled(False)
|
||||
self.checkBox_word.setText('Docx(暂时不可用)')
|
||||
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
|
||||
self.time_range = None
|
||||
|
||||
def set_export_date(self):
|
||||
date_range = self.comboBox_time.currentText()
|
||||
if date_range == '全部时间':
|
||||
pass
|
||||
elif date_range == '最近三个月':
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# 获取今天的日期和时间
|
||||
today = datetime.now()
|
||||
|
||||
# 获取今天的日期
|
||||
today_date = today.date()
|
||||
|
||||
# 获取今天的24:00:00的时间戳
|
||||
today_midnight = datetime.combine(today_date, datetime.min.time()) + timedelta(days=1)
|
||||
today_midnight_timestamp = int(today_midnight.timestamp())
|
||||
|
||||
# 获取三个月前的日期
|
||||
three_months_ago = today - timedelta(days=90)
|
||||
|
||||
# 获取三个月前的00:00:00的时间戳
|
||||
three_months_ago_date = three_months_ago.date()
|
||||
three_months_ago_midnight = datetime.combine(three_months_ago_date, datetime.min.time())
|
||||
three_months_ago_midnight_timestamp = int(three_months_ago_midnight.timestamp())
|
||||
self.time_range = (three_months_ago_midnight_timestamp, today_midnight_timestamp)
|
||||
|
||||
elif date_range == '自定义时间':
|
||||
self.time_range_view = TimeRangeDialog(parent=self)
|
||||
self.time_range_view.date_range_signal.connect(self.set_time_range)
|
||||
self.time_range_view.show()
|
||||
self.comboBox_time.setCurrentIndex(0)
|
||||
# QMessageBox.warning(self,
|
||||
# "别急别急",
|
||||
# "马上就实现该功能"
|
||||
# )
|
||||
|
||||
def set_time_range(self, time_range):
|
||||
self.time_range = time_range
|
||||
self.comboBox_time.setCurrentIndex(2)
|
||||
|
||||
def outputWritten(self, text):
|
||||
cursor = self.textBrowser.textCursor()
|
||||
cursor.movePosition(QTextCursor.End)
|
||||
cursor.insertText(text)
|
||||
self.textBrowser.setTextCursor(cursor)
|
||||
self.textBrowser.ensureCursorVisible()
|
||||
|
||||
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,self.checkBox_json]:
|
||||
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,
|
||||
time_range=self.time_range)
|
||||
# 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在{OUTPUT_DIR}目录下(跟exe文件在一起)\n{os.path.normpath(os.path.join(os.getcwd(), OUTPUT_DIR))}")
|
||||
reply.addButton("确认", QMessageBox.AcceptRole)
|
||||
reply.addButton("取消", QMessageBox.RejectRole)
|
||||
api = reply.exec_()
|
||||
# 在任务完成时重置sys.stdout
|
||||
sys_.stdout = sys_.__stdout__
|
||||
self.accept()
|
||||
|
||||
def close(self):
|
||||
sys_.stdout = sys_.__stdout__
|
||||
del self.worker
|
||||
super().close()
|
||||
|
||||
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_())
|
||||
166
app/ui/menu/exportUi.py
Normal file
166
app/ui/menu/exportUi.py
Normal file
@@ -0,0 +1,166 @@
|
||||
# -*- 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(791, 599)
|
||||
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.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label = QtWidgets.QLabel(Dialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy)
|
||||
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)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.checkBox_txt.sizePolicy().hasHeightForWidth())
|
||||
self.checkBox_txt.setSizePolicy(sizePolicy)
|
||||
self.checkBox_txt.setChecked(True)
|
||||
self.checkBox_txt.setObjectName("checkBox_txt")
|
||||
self.verticalLayout.addWidget(self.checkBox_txt)
|
||||
self.checkBox_json = QtWidgets.QCheckBox(Dialog)
|
||||
self.checkBox_json.setObjectName("checkBox_json")
|
||||
self.verticalLayout.addWidget(self.checkBox_json)
|
||||
self.label_2 = QtWidgets.QLabel(Dialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
|
||||
self.label_2.setSizePolicy(sizePolicy)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.verticalLayout.addWidget(self.label_2)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.verticalLayout.addLayout(self.verticalLayout_2)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem1)
|
||||
self.horizontalLayout_2.addLayout(self.verticalLayout)
|
||||
self.listWidget = QtWidgets.QListWidget(Dialog)
|
||||
self.listWidget.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.listWidget.setObjectName("listWidget")
|
||||
self.horizontalLayout_2.addWidget(self.listWidget)
|
||||
self.horizontalLayout_2.setStretch(0, 1)
|
||||
self.horizontalLayout_2.setStretch(1, 1)
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
|
||||
self.textBrowser = QtWidgets.QTextBrowser(Dialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.textBrowser.sizePolicy().hasHeightForWidth())
|
||||
self.textBrowser.setSizePolicy(sizePolicy)
|
||||
self.textBrowser.setMaximumSize(QtCore.QSize(16777215, 80))
|
||||
self.textBrowser.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.textBrowser.setTabStopWidth(0)
|
||||
self.textBrowser.setOpenExternalLinks(False)
|
||||
self.textBrowser.setObjectName("textBrowser")
|
||||
self.verticalLayout_3.addWidget(self.textBrowser)
|
||||
self.progressBar = QtWidgets.QProgressBar(Dialog)
|
||||
self.progressBar.setProperty("value", 0)
|
||||
self.progressBar.setObjectName("progressBar")
|
||||
self.verticalLayout_3.addWidget(self.progressBar)
|
||||
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout_4)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.label_time = QtWidgets.QLabel(Dialog)
|
||||
self.label_time.setText("")
|
||||
self.label_time.setObjectName("label_time")
|
||||
self.horizontalLayout_3.addWidget(self.label_time)
|
||||
self.label_process = QtWidgets.QLabel(Dialog)
|
||||
self.label_process.setText("")
|
||||
self.label_process.setObjectName("label_process")
|
||||
self.horizontalLayout_3.addWidget(self.label_process)
|
||||
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.setStyleSheet("QPushButton{\n"
|
||||
" background-color: rgb(233,233,233);\n"
|
||||
" border-radius: 5px;\n"
|
||||
" padding: 10px;\n"
|
||||
"}\n"
|
||||
"QPushButton:hover { \n"
|
||||
" background-color: lightgray;\n"
|
||||
"border:1px solid rgb(31,156,220) ;\n"
|
||||
"}")
|
||||
self.btn_start.setAutoDefault(False)
|
||||
self.btn_start.setDefault(False)
|
||||
self.btn_start.setFlat(False)
|
||||
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.checkBox_json.setText(_translate("Dialog", "JSON"))
|
||||
self.label_2.setText(_translate("Dialog", "消息类型"))
|
||||
self.btn_start.setText(_translate("Dialog", "开始"))
|
||||
109
app/ui/menu/export_time_range.py
Normal file
109
app/ui/menu/export_time_range.py
Normal file
@@ -0,0 +1,109 @@
|
||||
from datetime import datetime
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, Qt, QPoint
|
||||
from PyQt5.QtGui import QMouseEvent
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, QLabel
|
||||
|
||||
from app.components.calendar_dialog import CalendarDialog
|
||||
try:
|
||||
from .time_range import Ui_Dialog
|
||||
except:
|
||||
from time_range import Ui_Dialog
|
||||
Stylesheet = '''
|
||||
QToolButton{
|
||||
color:#000000;
|
||||
}
|
||||
QCalendarWidget QAbstractItemView:disabled {
|
||||
|
||||
}
|
||||
QCalendarWidget QAbstractItemView:enabled{
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
class TimeRangeDialog(QDialog, Ui_Dialog):
|
||||
date_range_signal = pyqtSignal(tuple)
|
||||
|
||||
def __init__(self, date_range=None, parent=None):
|
||||
"""
|
||||
|
||||
@param date_range: tuple[Union[QDate, datetime.date],Union[QDate, datetime.date]] 限定的可选择范围
|
||||
@param parent:
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.calendar = None
|
||||
self.setupUi(self)
|
||||
self.setWindowTitle('选择日期范围')
|
||||
# self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
|
||||
self.setStyleSheet(Stylesheet)
|
||||
self.toolButton_start_time.clicked.connect(self.select_date_start)
|
||||
self.toolButton_end_time.clicked.connect(self.select_date_end)
|
||||
self.calendar = CalendarDialog(date_range=date_range, parent=self)
|
||||
self.calendar.selected_date_signal.connect(self.set_date)
|
||||
self.btn_ok.clicked.connect(self.ok)
|
||||
self.btn_ok.setEnabled(False)
|
||||
self.btn_ok_num = 0
|
||||
self.btn_cancel.clicked.connect(lambda x: self.close())
|
||||
self.start_time_flag = True
|
||||
self.start_timestamp = 0
|
||||
self.end_timestamp = 0
|
||||
|
||||
def set_date(self, timestamp):
|
||||
if self.start_time_flag:
|
||||
self.start_timestamp = timestamp
|
||||
date_object = datetime.fromtimestamp(timestamp)
|
||||
str_start = date_object.strftime("%Y-%m-%d")
|
||||
self.toolButton_start_time.setText(str_start)
|
||||
self.btn_ok_num += 1
|
||||
else:
|
||||
date_object = datetime.fromtimestamp(timestamp)
|
||||
str_start = date_object.strftime("%Y-%m-%d")
|
||||
self.end_timestamp = timestamp + 86399
|
||||
self.toolButton_end_time.setText(str_start)
|
||||
self.btn_ok_num += 1
|
||||
if self.btn_ok_num == 2:
|
||||
self.btn_ok.setEnabled(True)
|
||||
|
||||
def ok(self):
|
||||
date_range = (self.start_timestamp, self.end_timestamp)
|
||||
self.date_range_signal.emit(date_range)
|
||||
self.close()
|
||||
|
||||
def select_date_start(self):
|
||||
self.start_time_flag = True
|
||||
self.calendar.set_start_date()
|
||||
self.calendar.show()
|
||||
|
||||
def select_date_end(self):
|
||||
self.start_time_flag = False
|
||||
self.calendar.set_end_date()
|
||||
self.calendar.show()
|
||||
|
||||
def mouseMoveEvent(self, e: QMouseEvent): # 重写移动事件
|
||||
if self._tracking:
|
||||
self._endPos = e.pos() - self._startPos
|
||||
self.move(self.pos() + self._endPos)
|
||||
|
||||
def mousePressEvent(self, e: QMouseEvent):
|
||||
if e.button() == Qt.LeftButton:
|
||||
self._startPos = QPoint(e.x(), e.y())
|
||||
self._tracking = True
|
||||
|
||||
def mouseReleaseEvent(self, e: QMouseEvent):
|
||||
if e.button() == Qt.LeftButton:
|
||||
self._tracking = False
|
||||
self._startPos = None
|
||||
self._endPos = None
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
# 设置日期范围
|
||||
start_date = datetime(2023, 12, 11)
|
||||
end_date = datetime(2024, 1, 9)
|
||||
date_range = (start_date.date(), end_date.date())
|
||||
ex = TimeRangeDialog(date_range=date_range)
|
||||
ex.show()
|
||||
sys.exit(app.exec_())
|
||||
73
app/ui/menu/time_range.py
Normal file
73
app/ui/menu/time_range.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'time_range.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(280, 200)
|
||||
Dialog.setMinimumSize(QtCore.QSize(280, 200))
|
||||
Dialog.setMaximumSize(QtCore.QSize(280, 200))
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label = QtWidgets.QLabel(Dialog)
|
||||
self.label.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label.setObjectName("label")
|
||||
self.verticalLayout.addWidget(self.label)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.label_2 = QtWidgets.QLabel(Dialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.horizontalLayout_2.addWidget(self.label_2)
|
||||
self.toolButton_start_time = QtWidgets.QToolButton(Dialog)
|
||||
self.toolButton_start_time.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
self.toolButton_start_time.setArrowType(QtCore.Qt.DownArrow)
|
||||
self.toolButton_start_time.setObjectName("toolButton_start_time")
|
||||
self.horizontalLayout_2.addWidget(self.toolButton_start_time)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
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)
|
||||
self.toolButton_end_time = QtWidgets.QToolButton(Dialog)
|
||||
self.toolButton_end_time.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
self.toolButton_end_time.setArrowType(QtCore.Qt.DownArrow)
|
||||
self.toolButton_end_time.setObjectName("toolButton_end_time")
|
||||
self.horizontalLayout.addWidget(self.toolButton_end_time)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.btn_ok = QtWidgets.QPushButton(Dialog)
|
||||
self.btn_ok.setObjectName("btn_ok")
|
||||
self.horizontalLayout_3.addWidget(self.btn_ok)
|
||||
self.btn_cancel = QtWidgets.QPushButton(Dialog)
|
||||
self.btn_cancel.setObjectName("btn_cancel")
|
||||
self.horizontalLayout_3.addWidget(self.btn_cancel)
|
||||
self.verticalLayout.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.setText(_translate("Dialog", "自定义时间"))
|
||||
self.label_2.setText(_translate("Dialog", "开始日期"))
|
||||
self.toolButton_start_time.setText(_translate("Dialog", "请选择时间"))
|
||||
self.label_3.setText(_translate("Dialog", "结束日期"))
|
||||
self.toolButton_end_time.setText(_translate("Dialog", "请选择时间"))
|
||||
self.btn_ok.setText(_translate("Dialog", "确定"))
|
||||
self.btn_cancel.setText(_translate("Dialog", "取消"))
|
||||
Reference in New Issue
Block a user