diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index 842784c..c41dc49 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -233,7 +233,7 @@ class Msg: # result.sort(key=lambda x: x[5]) return parser_chatroom_message(result) if username_.__contains__('@chatroom') else result - def get_messages_by_type(self, username_, type_, year_='all',time_range=None): + def get_messages_by_type(self, username_, type_, year_='all', time_range=None): if not self.open_flag: return None if time_range: @@ -344,6 +344,28 @@ class Msg: contacts.sort(key=lambda cur_contact: cur_contact[-1], reverse=True) return contacts + def get_messages_calendar(self, username_): + sql = ''' + SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days + from ( + SELECT MsgSvrID, CreateTime + FROM MSG + WHERE StrTalker = ? + ORDER BY CreateTime + ) + group by days + ''' + if not self.open_flag: + print('数据库未就绪') + return None + try: + lock.acquire(True) + self.cursor.execute(sql, [username_]) + result = self.cursor.fetchall() + finally: + lock.release() + return [date[0] for date in result] + def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'): if is_Annual_report_: sql = ''' @@ -694,39 +716,11 @@ class Msg: if __name__ == '__main__': - db_path = "./app/database/Msg/MSG.db" + db_path = "./Msg/MSG.db" msg = Msg() msg.init_database() wxid = 'wxid_0o18ef858vnu22' wxid = '24521163022@chatroom' wxid = 'wxid_vtz9jk9ulzjt22' # si print() - from app.util import compress_content - import xml.etree.ElementTree as ET - - msgs = msg.get_messages(wxid) - - for msg in msgs: - if msg[2] == 49 and msg[3] == 5: - xml = compress_content.decompress_CompressContent(msg[11]) - root = ET.XML(xml) - appmsg = root.find('appmsg') - title = appmsg.find('title').text - des = appmsg.find('des').text - url = appmsg.find('url').text - appinfo = root.find('appinfo') - show_display_name = appmsg.find('sourcedisplayname') - if show_display_name is not None: - show_display_name = show_display_name.text - else: - show_display_name = appinfo.find('appname').text - print(title, des, url, show_display_name) - msg_bytes = MessageBytesExtra() - msg_bytes.ParseFromString(msg[10]) - for tmp in msg_bytes.message2: - if tmp.field1 == 3: - thumb = tmp.field2 - print(thumb) - if tmp.field2 == 4: - app_logo = tmp.field2 - print('logo', app_logo) + print(msg.get_messages_calendar(wxid)) diff --git a/app/components/calendar_dialog.py b/app/components/calendar_dialog.py index f38026b..91898ef 100644 --- a/app/components/calendar_dialog.py +++ b/app/components/calendar_dialog.py @@ -1,8 +1,12 @@ import time -from PyQt5 import QtWidgets -from PyQt5.QtCore import QTimer, QThread, pyqtSignal -from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout +from datetime import datetime, timedelta +from PyQt5.QtCore import QTimer, QThread, pyqtSignal, Qt +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, \ + QToolButton + +from app.ui.Icon import Icon class CalendarDialog(QDialog): @@ -18,12 +22,37 @@ class CalendarDialog(QDialog): self.setWindowTitle('选择日期') self.calendar = QCalendarWidget(self) self.calendar.clicked.connect(self.onDateChanged) + prev_btn = self.calendar.findChild(QToolButton, "qt_calendar_prevmonth") + prev_btn.setIcon(Icon.Arrow_left_Icon) + next_btn = self.calendar.findChild(QToolButton, "qt_calendar_nextmonth") + next_btn.setIcon(Icon.Arrow_right_Icon) + self.date_range = date_range if date_range: self.calendar.setDateRange(*date_range) + # 从第一天开始,依次添加日期到列表,直到该月的最后一天 + current_date = date_range[1] + while (current_date + timedelta(days=1)).month == date_range[1].month: + current_date += timedelta(days=1) + range_format = self.calendar.dateTextFormat(current_date) + range_format.setForeground(Qt.gray) + self.calendar.setDateTextFormat(current_date, range_format) + # 从第一天开始,依次添加日期到列表,直到该月的最后一天 + current_date = date_range[0] + while (current_date - timedelta(days=1)).month == date_range[0].month: + current_date -= timedelta(days=1) + range_format = self.calendar.dateTextFormat(current_date) + range_format.setForeground(Qt.gray) + self.calendar.setDateTextFormat(current_date, range_format) layout = QVBoxLayout(self) layout.addWidget(self.calendar) self.setLayout(layout) + def set_start_date(self): + if self.date_range: + self.calendar.setCurrentPage(self.date_range[0].year, self.date_range[0].month) + def set_end_date(self): + if self.date_range: + self.calendar.setCurrentPage(self.date_range[1].year, self.date_range[1].month) def onDateChanged(self): # 获取选择的日期 selected_date = self.calendar.selectedDate() @@ -37,11 +66,11 @@ class CalendarDialog(QDialog): if __name__ == '__main__': import sys - from datetime import datetime + from datetime import datetime, timedelta app = QApplication(sys.argv) # 设置日期范围 - start_date = datetime(2023, 12, 11) + start_date = datetime(2024, 1, 5) end_date = datetime(2024, 1, 9) date_range = (start_date.date(), end_date.date()) ex = CalendarDialog(date_range=date_range) diff --git a/app/resources/icons/arrow-left.svg b/app/resources/icons/arrow-left.svg new file mode 100644 index 0000000..7d5f037 --- /dev/null +++ b/app/resources/icons/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/resources/icons/arrow-right.svg b/app/resources/icons/arrow-right.svg new file mode 100644 index 0000000..47b6761 --- /dev/null +++ b/app/resources/icons/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/resources/resource.qrc b/app/resources/resource.qrc index 9dc8036..b4edd97 100644 --- a/app/resources/resource.qrc +++ b/app/resources/resource.qrc @@ -41,5 +41,7 @@ icons/woman.svg icons/select.svg icons/unselect.svg + icons/arrow-left.svg + icons/arrow-right.svg diff --git a/app/resources/resource_rc.py b/app/resources/resource_rc.py index 6811953..bada8d0 100644 --- a/app/resources/resource_rc.py +++ b/app/resources/resource_rc.py @@ -16768,6 +16768,62 @@ qt_resource_data = b"\ \x22\x20\x66\x69\x6c\x6c\x3d\x22\x23\x46\x46\x37\x42\x31\x35\x22\ \x20\x70\x2d\x69\x64\x3d\x22\x32\x36\x30\x33\x33\x22\x3e\x3c\x2f\ \x70\x61\x74\x68\x3e\x3c\x2f\x73\x76\x67\x3e\ +\x00\x00\x03\x5f\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\x6e\ +\x6f\x22\x3f\x3e\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\x76\ +\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\x43\ +\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\x45\ +\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\ +\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\x53\ +\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\x31\ +\x2e\x64\x74\x64\x22\x3e\x3c\x73\x76\x67\x20\x74\x3d\x22\x31\x37\ +\x30\x34\x38\x38\x37\x36\x34\x33\x37\x39\x31\x22\x20\x63\x6c\x61\ +\x73\x73\x3d\x22\x69\x63\x6f\x6e\x22\x20\x76\x69\x65\x77\x42\x6f\ +\x78\x3d\x22\x30\x20\x30\x20\x31\x30\x32\x34\x20\x31\x30\x32\x34\ +\x22\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\ +\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\ +\x67\x22\x20\x70\x2d\x69\x64\x3d\x22\x36\x31\x35\x36\x22\x20\x78\ +\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\ +\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x36\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x22\ +\x3e\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x30\x33\x2e\x33\ +\x34\x32\x39\x39\x37\x20\x38\x37\x2e\x30\x31\x33\x38\x39\x36\x61\ +\x34\x37\x2e\x39\x30\x38\x38\x32\x37\x20\x34\x37\x2e\x39\x30\x38\ +\x38\x32\x37\x20\x30\x20\x30\x20\x30\x20\x30\x2d\x37\x30\x2e\x39\ +\x39\x33\x31\x30\x32\x41\x36\x31\x2e\x34\x32\x31\x35\x37\x34\x20\ +\x36\x31\x2e\x34\x32\x31\x35\x37\x34\x20\x30\x20\x30\x20\x30\x20\ +\x37\x32\x33\x2e\x39\x30\x34\x34\x32\x39\x20\x31\x33\x2e\x32\x35\ +\x36\x38\x32\x33\x6c\x2d\x33\x2e\x31\x37\x33\x34\x34\x38\x20\x32\ +\x2e\x37\x36\x33\x39\x37\x31\x4c\x32\x34\x31\x2e\x32\x33\x33\x32\ +\x33\x20\x34\x37\x30\x2e\x39\x34\x39\x39\x31\x35\x6c\x2d\x32\x2e\ +\x34\x30\x35\x36\x37\x38\x20\x31\x2e\x38\x34\x32\x36\x34\x37\x63\ +\x2d\x31\x2e\x36\x33\x37\x39\x30\x39\x20\x31\x2e\x32\x32\x38\x34\ +\x33\x31\x2d\x33\x2e\x31\x37\x33\x34\x34\x38\x20\x32\x2e\x35\x35\ +\x39\x32\x33\x32\x2d\x34\x2e\x36\x30\x36\x36\x31\x38\x20\x33\x2e\ +\x39\x34\x31\x32\x31\x38\x2d\x32\x30\x2e\x30\x31\x33\x31\x39\x36\ +\x20\x31\x38\x2e\x39\x33\x38\x33\x31\x39\x2d\x32\x30\x2e\x39\x38\ +\x35\x37\x30\x34\x20\x34\x38\x2e\x31\x31\x33\x35\x36\x36\x2d\x32\ +\x2e\x38\x36\x36\x33\x34\x20\x36\x38\x2e\x30\x37\x35\x35\x37\x37\ +\x6c\x32\x2e\x38\x31\x35\x31\x35\x35\x20\x32\x2e\x39\x31\x37\x35\ +\x32\x35\x20\x34\x38\x34\x2e\x38\x32\x30\x39\x35\x34\x20\x34\x35\ +\x39\x2e\x39\x34\x35\x32\x31\x36\x63\x32\x32\x2e\x35\x32\x31\x32\ +\x34\x34\x20\x32\x31\x2e\x33\x34\x33\x39\x39\x37\x20\x36\x30\x2e\ +\x30\x39\x30\x37\x37\x33\x20\x32\x31\x2e\x33\x34\x33\x39\x39\x37\ +\x20\x38\x32\x2e\x36\x31\x32\x30\x31\x36\x20\x30\x20\x32\x30\x2e\ +\x30\x31\x33\x31\x39\x36\x2d\x31\x38\x2e\x39\x33\x38\x33\x31\x39\ +\x20\x32\x30\x2e\x39\x38\x35\x37\x30\x34\x2d\x34\x38\x2e\x31\x31\ +\x33\x35\x36\x36\x20\x32\x2e\x38\x36\x36\x33\x34\x2d\x36\x38\x2e\ +\x30\x37\x35\x35\x37\x37\x6c\x2d\x32\x2e\x38\x36\x36\x33\x34\x2d\ +\x32\x2e\x39\x36\x38\x37\x30\x39\x2d\x34\x34\x36\x2e\x38\x39\x33\ +\x31\x33\x32\x2d\x34\x32\x33\x2e\x39\x31\x31\x32\x32\x37\x4c\x38\ +\x30\x33\x2e\x33\x34\x32\x39\x39\x37\x20\x38\x37\x2e\x30\x31\x33\ +\x38\x39\x36\x7a\x22\x20\x66\x69\x6c\x6c\x3d\x22\x23\x33\x30\x33\ +\x31\x33\x33\x22\x20\x70\x2d\x69\x64\x3d\x22\x36\x31\x35\x37\x22\ +\x3e\x3c\x2f\x70\x61\x74\x68\x3e\x3c\x2f\x73\x76\x67\x3e\ \x00\x00\x09\xf9\ \x3c\ \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ @@ -19560,6 +19616,50 @@ qt_resource_data = b"\ \x91\x45\x16\x59\x64\x91\x45\x16\xff\xa5\x50\xea\xff\x03\xa2\x62\ \xb7\x9c\xc4\xc5\xc1\xc0\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\ \x60\x82\ +\x00\x00\x02\x99\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\x6e\ +\x6f\x22\x3f\x3e\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\x76\ +\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\x43\ +\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\x45\ +\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\ +\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\x53\ +\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\x31\ +\x2e\x64\x74\x64\x22\x3e\x3c\x73\x76\x67\x20\x74\x3d\x22\x31\x37\ +\x30\x34\x38\x38\x37\x36\x38\x34\x30\x32\x39\x22\x20\x63\x6c\x61\ +\x73\x73\x3d\x22\x69\x63\x6f\x6e\x22\x20\x76\x69\x65\x77\x42\x6f\ +\x78\x3d\x22\x30\x20\x30\x20\x31\x30\x32\x34\x20\x31\x30\x32\x34\ +\x22\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\ +\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\ +\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\ +\x67\x22\x20\x70\x2d\x69\x64\x3d\x22\x37\x31\x33\x30\x22\x20\x78\ +\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\ +\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x77\x69\x64\x74\x68\x3d\ +\x22\x31\x36\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x22\ +\x3e\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x34\x30\x2e\x38\ +\x37\x31\x36\x39\x34\x20\x39\x37\x2e\x31\x31\x37\x33\x31\x34\x61\ +\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\ +\x34\x20\x30\x20\x30\x20\x31\x20\x30\x2d\x38\x30\x2e\x34\x36\x31\ +\x37\x37\x35\x20\x35\x38\x2e\x31\x31\x30\x33\x39\x33\x20\x35\x38\ +\x2e\x31\x31\x30\x33\x39\x33\x20\x30\x20\x30\x20\x31\x20\x38\x31\ +\x2e\x34\x36\x39\x37\x34\x36\x20\x30\x6c\x34\x36\x30\x2e\x37\x38\ +\x37\x32\x35\x37\x20\x34\x35\x35\x2e\x31\x30\x37\x34\x31\x34\x61\ +\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\ +\x34\x20\x30\x20\x30\x20\x31\x20\x30\x20\x38\x30\x2e\x34\x34\x35\ +\x37\x37\x35\x4c\x33\x32\x32\x2e\x33\x34\x31\x34\x34\x20\x31\x30\ +\x30\x37\x2e\x33\x33\x32\x31\x34\x31\x61\x35\x38\x2e\x31\x31\x30\ +\x33\x39\x33\x20\x35\x38\x2e\x31\x31\x30\x33\x39\x33\x20\x30\x20\ +\x30\x20\x31\x2d\x38\x31\x2e\x34\x36\x39\x37\x34\x36\x20\x30\x20\ +\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\ +\x34\x20\x30\x20\x30\x20\x31\x20\x30\x2d\x38\x30\x2e\x34\x36\x31\ +\x37\x37\x35\x4c\x36\x36\x30\x2e\x39\x35\x36\x30\x37\x36\x20\x35\ +\x31\x31\x2e\x39\x38\x35\x38\x34\x20\x32\x34\x30\x2e\x38\x37\x31\ +\x36\x39\x34\x20\x39\x37\x2e\x31\x31\x37\x33\x31\x34\x7a\x22\x20\ +\x66\x69\x6c\x6c\x3d\x22\x23\x31\x31\x31\x31\x31\x31\x22\x20\x70\ +\x2d\x69\x64\x3d\x22\x37\x31\x33\x31\x22\x3e\x3c\x2f\x70\x61\x74\ +\x68\x3e\x3c\x2f\x73\x76\x67\x3e\ \x00\x00\x05\x66\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -20457,6 +20557,10 @@ qt_resource_name = b"\ \x08\x97\xaf\x87\ \x00\x73\ \x00\x74\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ +\x00\x0e\ +\x08\xfa\x38\xa7\ +\x00\x61\ +\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x07\ \x0a\xa9\x5a\x07\ \x00\x63\ @@ -20493,6 +20597,10 @@ qt_resource_name = b"\ \x0f\x0e\xef\x47\ \x00\x77\ \x00\x65\x00\x69\x00\x78\x00\x69\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0f\ +\x0f\x22\x69\x47\ +\x00\x61\ +\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x05\ \x00\x33\x57\x47\ \x00\x30\ @@ -20530,7 +20638,7 @@ qt_resource_name = b"\ qt_resource_struct_v1 = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x22\x00\x00\x00\x03\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x24\x00\x00\x00\x03\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x13\x52\ \x00\x00\x00\x50\x00\x01\x00\x00\x00\x01\x00\x00\x19\x78\ @@ -20557,22 +20665,24 @@ qt_resource_struct_v1 = b"\ \x00\x00\x02\x76\x00\x00\x00\x00\x00\x01\x00\x04\x0c\x41\ \x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\ \x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\ -\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x04\x1e\x0f\ -\x00\x00\x02\xd6\x00\x02\x00\x00\x00\x08\x00\x00\x00\x25\ -\x00\x00\x02\xea\x00\x00\x00\x00\x00\x01\x00\x04\x26\x4a\ -\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x04\x2e\x00\ -\x00\x00\x03\x1a\x00\x00\x00\x00\x00\x01\x00\x04\x31\x18\ -\x00\x00\x03\x2e\x00\x00\x00\x00\x00\x01\x00\x04\x34\x91\ -\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x04\x3d\x9c\ -\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x04\x44\xe1\ -\x00\x00\x03\x74\x00\x00\x00\x00\x00\x01\x00\x04\xc1\x58\ -\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x04\xc6\xc2\ -\x00\x00\x03\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcc\x40\ -\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x63\ -\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x6c\ -\x00\x00\x03\xc4\x00\x00\x00\x00\x00\x01\x00\x04\xde\x8f\ -\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x04\xe4\xd0\ -\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x04\xeb\x23\ +\x00\x00\x02\xca\x00\x00\x00\x00\x00\x01\x00\x04\x17\x75\ +\x00\x00\x02\xde\x00\x00\x00\x00\x00\x01\x00\x04\x21\x72\ +\x00\x00\x02\xf8\x00\x02\x00\x00\x00\x08\x00\x00\x00\x27\ +\x00\x00\x03\x0c\x00\x00\x00\x00\x00\x01\x00\x04\x29\xad\ +\x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x04\x31\x63\ +\x00\x00\x03\x3c\x00\x00\x00\x00\x00\x01\x00\x04\x34\x7b\ +\x00\x00\x03\x50\x00\x00\x00\x00\x00\x01\x00\x04\x37\xf4\ +\x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x04\x40\xff\ +\x00\x00\x03\x7c\x00\x00\x00\x00\x00\x01\x00\x04\x48\x44\ +\x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x04\xc4\xbb\ +\x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x04\xc7\x58\ +\x00\x00\x03\xca\x00\x00\x00\x00\x00\x01\x00\x04\xcc\xc2\ +\x00\x00\x03\xda\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x40\ +\x00\x00\x03\xea\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x63\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x04\xde\x6c\ +\x00\x00\x04\x0a\x00\x00\x00\x00\x00\x01\x00\x04\xe4\x8f\ +\x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x04\xea\xd0\ +\x00\x00\x04\x2a\x00\x00\x00\x00\x00\x01\x00\x04\xf1\x23\ " qt_resource_struct_v2 = b"\ @@ -20580,7 +20690,7 @@ qt_resource_struct_v2 = b"\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x22\x00\x00\x00\x03\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x24\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x01\x8c\x68\xa4\x46\x85\ @@ -20633,38 +20743,42 @@ qt_resource_struct_v2 = b"\ \x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\ \x00\x00\x01\x8c\x68\xa6\x6b\x89\ \x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\ +\x00\x00\x01\x8c\xf3\x38\xf8\x1c\ +\x00\x00\x02\xca\x00\x00\x00\x00\x00\x01\x00\x04\x17\x75\ \x00\x00\x01\x8c\x16\x33\xc3\xa4\ -\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x04\x1e\x0f\ +\x00\x00\x02\xde\x00\x00\x00\x00\x00\x01\x00\x04\x21\x72\ \x00\x00\x01\x8c\x68\xa5\xb8\xe6\ -\x00\x00\x02\xd6\x00\x02\x00\x00\x00\x08\x00\x00\x00\x25\ +\x00\x00\x02\xf8\x00\x02\x00\x00\x00\x08\x00\x00\x00\x27\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x02\xea\x00\x00\x00\x00\x00\x01\x00\x04\x26\x4a\ +\x00\x00\x03\x0c\x00\x00\x00\x00\x00\x01\x00\x04\x29\xad\ \x00\x00\x01\x8c\x16\x33\xc3\xa5\ -\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x04\x2e\x00\ +\x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x04\x31\x63\ \x00\x00\x01\x8c\xee\x70\x7d\x1b\ -\x00\x00\x03\x1a\x00\x00\x00\x00\x00\x01\x00\x04\x31\x18\ +\x00\x00\x03\x3c\x00\x00\x00\x00\x00\x01\x00\x04\x34\x7b\ \x00\x00\x01\x8c\x68\x2b\xa2\xb9\ -\x00\x00\x03\x2e\x00\x00\x00\x00\x00\x01\x00\x04\x34\x91\ +\x00\x00\x03\x50\x00\x00\x00\x00\x00\x01\x00\x04\x37\xf4\ \x00\x00\x01\x8c\x68\xa8\x53\x77\ -\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x04\x3d\x9c\ +\x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x04\x40\xff\ \x00\x00\x01\x8c\x68\x9c\x76\x1a\ -\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x04\x44\xe1\ +\x00\x00\x03\x7c\x00\x00\x00\x00\x00\x01\x00\x04\x48\x44\ \x00\x00\x01\x8c\x9b\xb4\x01\x0f\ -\x00\x00\x03\x74\x00\x00\x00\x00\x00\x01\x00\x04\xc1\x58\ +\x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x04\xc4\xbb\ +\x00\x00\x01\x8c\xf3\x39\x91\xdd\ +\x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x04\xc7\x58\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x04\xc6\xc2\ +\x00\x00\x03\xca\x00\x00\x00\x00\x00\x01\x00\x04\xcc\xc2\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcc\x40\ +\x00\x00\x03\xda\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x40\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x63\ +\x00\x00\x03\xea\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x63\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x6c\ +\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x04\xde\x6c\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\xc4\x00\x00\x00\x00\x00\x01\x00\x04\xde\x8f\ +\x00\x00\x04\x0a\x00\x00\x00\x00\x00\x01\x00\x04\xe4\x8f\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x04\xe4\xd0\ +\x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x04\xea\xd0\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ -\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x04\xeb\x23\ +\x00\x00\x04\x2a\x00\x00\x00\x00\x00\x01\x00\x04\xf1\x23\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\ " diff --git a/app/ui/Icon.py b/app/ui/Icon.py index d63dead..4e34fd2 100644 --- a/app/ui/Icon.py +++ b/app/ui/Icon.py @@ -36,6 +36,8 @@ class Icon: Woman_Icon_path = ':/icons/icons/woman.svg' Man_Icon = QIcon(':/icons/icons/man.svg') Woman_Icon = QIcon(':/icons/icons/woman.svg') + Arrow_left_Icon = QIcon(':/icons/icons/arrow-left.svg') + Arrow_right_Icon = QIcon(':/icons/icons/arrow-right.svg') # Man_Icon_pixmap = QPixmap(Man_Icon_path) # Woman_Icon_pixmap = QPixmap(Woman_Icon_path) # Logo_Icon = QIcon(':/icons/icons/logo.png') diff --git a/app/ui/contact/contactInfo.py b/app/ui/contact/contactInfo.py index 1b26047..0d11f1e 100644 --- a/app/ui/contact/contactInfo.py +++ b/app/ui/contact/contactInfo.py @@ -1,13 +1,12 @@ from PyQt5.QtCore import pyqtSignal, QUrl, QThread from PyQt5.QtGui import QDesktopServices -from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox, QDialog +from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox -from app.DataBase.output_pc import Output from app.ui.Icon import Icon from .contactInfoUi import Ui_Form from .userinfo import userinfo from ...person import Contact, Me -from .export_dialog import ExportDialog +from app.ui.contact.export.export_dialog import ExportDialog class ContactInfo(QWidget, Ui_Form): diff --git a/app/ui/contact/export/__init__.py b/app/ui/contact/export/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/ui/contact/export/exportUi.py b/app/ui/contact/export/exportUi.py new file mode 100644 index 0000000..05c8549 --- /dev/null +++ b/app/ui/contact/export/exportUi.py @@ -0,0 +1,91 @@ +# -*- 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_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.horizontalLayout_2.setStretch(0, 1) + 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") + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem1) + self.btn_start = QtWidgets.QPushButton(Dialog) + self.btn_start.setObjectName("btn_start") + self.horizontalLayout_3.addWidget(self.btn_start) + self.btn_cancel = QtWidgets.QPushButton(Dialog) + self.btn_cancel.setObjectName("btn_cancel") + self.horizontalLayout_3.addWidget(self.btn_cancel) + 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_2.setText(_translate("Dialog", "消息类型")) + self.btn_start.setText(_translate("Dialog", "开始")) + self.btn_cancel.setText(_translate("Dialog", "取消")) diff --git a/app/ui/contact/export_dialog.py b/app/ui/contact/export/export_dialog.py similarity index 53% rename from app/ui/contact/export_dialog.py rename to app/ui/contact/export/export_dialog.py index bc1f957..11186e8 100644 --- a/app/ui/contact/export_dialog.py +++ b/app/ui/contact/export/export_dialog.py @@ -1,9 +1,13 @@ +import os import time - +from datetime import datetime, timedelta from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \ QProgressBar, QLabel, QMessageBox, QComboBox +from app.DataBase import msg_db +from app.ui.menu.export_time_range import TimeRangeDialog +from .exportUi import Ui_Dialog from app.DataBase.output_pc import Output types = { @@ -14,7 +18,7 @@ types = { '表情包': 47, '音乐与音频': 4903, '文件': 4906, - '分享卡片':4905, + '分享卡片': 4905, '拍一拍等系统消息': 10000 } Stylesheet = """ @@ -27,15 +31,18 @@ QPushButton:hover { """ -class ExportDialog(QDialog): +class ExportDialog(QDialog, Ui_Dialog): def __init__(self, contact=None, title="选择导出的类型", file_type="csv", parent=None): super(ExportDialog, self).__init__(parent) + self.select_all_flag = False + self.setupUi(self) self.setStyleSheet(Stylesheet) + self.contact = contact if file_type == 'html': self.export_type = Output.HTML self.export_choices = {"文本": True, "图片": True, "语音": False, "视频": False, "表情包": False, - '音乐与音频': False,'分享卡片':False,'文件': False, + '音乐与音频': False, '分享卡片': False, '文件': False, '拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择 elif file_type == 'csv': self.export_type = Output.CSV @@ -48,53 +55,40 @@ class ExportDialog(QDialog): elif file_type == 'docx': self.export_type = Output.DOCX self.export_choices = {"文本": True, "图片": False, "语音": False, "视频": False, - "表情包": False,'拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择 + "表情包": False, '拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择 else: self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择 self.setWindowTitle(title) - layout = QVBoxLayout(self) self.resize(400, 300) self.worker = None # 导出线程 - self.progress_bar = QProgressBar(self) - self.progress_label = QLabel(self) - self.time_label = QLabel(self) + for export_type, default_state in self.export_choices.items(): checkbox = QCheckBox(export_type) checkbox.setChecked(default_state) - layout.addWidget(checkbox) - layout.addWidget(self.progress_bar) - layout.addWidget(self.progress_label) - layout.addWidget(self.time_label) - self.notice_label = QLabel(self) - self.notice_label.setText( - "注意:导出HTML时选择图片、视频、语音、文件、音乐与音频、表情包(特别是表情包)\n会导致大大影响导出速度,请合理选择导出的类型") - layout.addWidget(self.notice_label) - hlayout = QHBoxLayout(self) - self.export_button = QPushButton("导出") - self.export_button.clicked.connect(self.export_data) - hlayout.addWidget(self.export_button) + self.verticalLayout_2.addWidget(checkbox) - self.cancel_button = QPushButton("取消") - self.cancel_button.clicked.connect(self.reject) # 使用reject关闭对话框 - hlayout.addWidget(self.cancel_button) - layout.addLayout(hlayout) - self.setLayout(layout) + self.btn_select_all.clicked.connect(self.select_all) + self.btn_start.clicked.connect(self.export_data) + self.btn_cancel.clicked.connect(self.reject) # 使用reject关闭对话框 + self.comboBox_time.activated.connect(self.set_export_date) self.timer = QTimer(self) self.time = 0 self.total_msg_num = 99999 # 总的消息个数 self.num = 0 # 当前完成的消息个数 self.timer.timeout.connect(self.update_elapsed_time) + self.time_range = None def export_data(self): - self.export_button.setEnabled(False) - self.cancel_button.setEnabled(False) + self.btn_start.setEnabled(False) + self.btn_cancel.setEnabled(False) # 在这里获取用户选择的导出数据类型 selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in zip(self.export_choices.keys(), self.findChildren(QCheckBox))} # 在这里根据用户选择的数据类型执行导出操作 print("选择的数据类型:", selected_types) - self.worker = Output(self.contact, type_=self.export_type, message_types=selected_types) + self.worker = Output(self.contact, type_=self.export_type, message_types=selected_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) @@ -104,34 +98,92 @@ class ExportDialog(QDialog): self.start_time = time.time() # self.accept() # 使用accept关闭对话框 + def set_export_date(self): + date_range = self.comboBox_time.currentText() + if date_range == '全部时间': + pass + elif date_range == '最近三个月': + + + # 获取今天的日期和时间 + 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 == '自定义时间': + date_range = None + chat_calendar = msg_db.get_messages_calendar(self.contact.wxid) + if chat_calendar: + start_time = datetime.strptime(chat_calendar[0], "%Y-%m-%d") + end_time = datetime.strptime(chat_calendar[-1], "%Y-%m-%d") + date_range = (start_time.date(),end_time.date()) + self.time_range_view = TimeRangeDialog(date_range=date_range,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 set_total_msg_num(self, num): self.total_msg_num = num # b''+num +(1,1) def export_finished(self): - self.export_button.setEnabled(True) - self.cancel_button.setEnabled(True) + self.btn_start.setEnabled(True) + self.btn_cancel.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.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)\n{os.getcwd()}\\data\\") reply.addButton("确认", QMessageBox.AcceptRole) reply.addButton("取消", QMessageBox.RejectRole) api = reply.exec_() self.accept() + def select_all(self): + self.select_all_flag = not self.select_all_flag + print('全选', self.select_all_flag) + if self.select_all_flag: + for checkbox in self.findChildren(QCheckBox): + checkbox.setChecked(True) + self.btn_select_all.setText('全不选') + else: + for checkbox in self.findChildren(QCheckBox): + checkbox.setChecked(False) + self.btn_select_all.setText('全选') + def update_elapsed_time(self): self.time += 1 - self.time_label.setText(f"耗时: {self.time}s") + self.label_time.setText(f"耗时: {self.time}s") def update_progress(self, progress_percentage): self.num += 1 progress_percentage = int((self.num) / self.total_msg_num * 100) - self.progress_bar.setValue(progress_percentage) - self.progress_label.setText(f"导出进度: {progress_percentage}%") + self.progressBar.setValue(progress_percentage) + self.label_process.setText(f"导出进度: {progress_percentage}%") if __name__ == '__main__': diff --git a/app/ui/menu/export_time_range.py b/app/ui/menu/export_time_range.py index 6b0a81d..eeb5098 100644 --- a/app/ui/menu/export_time_range.py +++ b/app/ui/menu/export_time_range.py @@ -4,12 +4,19 @@ from PyQt5.QtCore import QTimer, QThread, pyqtSignal from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, QLabel from app.components.calendar_dialog import CalendarDialog -from .time_range import Ui_Dialog - +try: + from .time_range import Ui_Dialog +except: + from time_range import Ui_Dialog Stylesheet = ''' QToolButton{ color:#000000; } +QCalendarWidget QAbstractItemView:disabled { + +} +QCalendarWidget QAbstractItemView:enabled{ +} ''' @@ -32,6 +39,8 @@ class TimeRangeDialog(QDialog, Ui_Dialog): 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 @@ -43,11 +52,15 @@ class TimeRangeDialog(QDialog, Ui_Dialog): 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) @@ -56,10 +69,12 @@ class TimeRangeDialog(QDialog, Ui_Dialog): 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() @@ -72,6 +87,6 @@ if __name__ == '__main__': start_date = datetime(2023, 12, 11) end_date = datetime(2024, 1, 9) date_range = (start_date.date(), end_date.date()) - ex = CalendarDialog(date_range=date_range) + ex = TimeRangeDialog(date_range=date_range) ex.show() sys.exit(app.exec_()) diff --git a/app/ui/menu/time_range.py b/app/ui/menu/time_range.py index 2f640ad..97e1813 100644 --- a/app/ui/menu/time_range.py +++ b/app/ui/menu/time_range.py @@ -46,6 +46,8 @@ class Ui_Dialog(object): 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) diff --git a/doc/images/contact_info.png b/doc/images/contact_info.png new file mode 100644 index 0000000..afb6e9b Binary files /dev/null and b/doc/images/contact_info.png differ