From cb194bc5ab1bc43ea0007931cd980765493f98dd Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 4 Jun 2023 14:10:30 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/budget/_trans.py | 94 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/src/budget/_trans.py b/src/budget/_trans.py index d5ccf5f..693f4af 100644 --- a/src/budget/_trans.py +++ b/src/budget/_trans.py @@ -10,7 +10,6 @@ class TransTab(TabPage): super().__init__() self.initUI() self.pg = parent.pg - self.rows = [] def initUI(self): # 创建顶部控件 @@ -124,7 +123,98 @@ class TransTab(TabPage): QMessageBox.critical(self, 'Error', str(e)) def onTransModifyClicked(self): - pass + # 获取当前选择的行 + self.rows = self.transTable.selectionModel().selectedRows() + if len(self.rows) == 0: + QMessageBox.critical(self, 'Error', 'No row selected') + return + + # 创建修改数据对话框 + self.tDialog = QDialog(self) + self.tDialog.setWindowTitle('Modify Transaction')# 时间 金额 描述 + timeLabel=QLabel("Time:") + timeLine=QLineEdit() + timeLine.setText(self.transData[self.rows[0].row()][4].strftime("%Y-%m-%d %H:%M:%S")) + + amountLabel = QLabel("Amount:") + amountLine = QLineEdit() + num = self.transData[self.rows[0].row()][5] + # 去掉¥符号 + num = num[1:] + amountLine.setText(num) + # 只允许输入两位小数 + amountLine.setValidator(QDoubleValidator(0.00, 999999999.99, 2)) + + descriptionLabel = QLabel("Description:") + descriptionLine = QLineEdit() + descriptionLine.setText(self.transData[self.rows[0].row()][6]) + + cButton = QPushButton("Confirm") + aButton = QPushButton("Abort") + buttonLayout = QHBoxLayout() + buttonLayout.addWidget(cButton) + buttonLayout.addWidget(aButton) + + cButton.clicked.connect(self.tDialog.accept) + aButton.clicked.connect(self.tDialog.reject) + + self.dialogLayout = QFormLayout() + self.dialogLayout.addRow(timeLabel, timeLine) + self.dialogLayout.addRow(amountLabel, amountLine) + self.dialogLayout.addRow(descriptionLabel, descriptionLine) + self.dialogLayout.addRow(buttonLayout) + self.dialogLayout.setSpacing(12) + self.dialogLayout.setContentsMargins(15, 15, 15, 15) + + self.tDialog.setMinimumWidth(400) + self.tDialog.setLayout(self.dialogLayout) + + if self.tDialog.exec() == QDialog.DialogCode.Accepted: + try: + # 若修改金额,则修改账户余额 + if num != amountLine.text(): + amount = float(amountLine.text()) + amount = amount - float(num) + print(amount) + self.pg.execute("UPDATE account SET balance = balance + (%s::NUMERIC)::MONEY WHERE a_id = %s",\ + (amount, self.transData[self.rows[0].row()][1],)) + + # 检测时间格式 + time = timeLine.text() + time = datetime.datetime.strptime(time, "%Y-%m-%d %H:%M:%S") + + # 把 meta 取回来 + self.pg.execute("SELECT meta FROM transaction WHERE t_id = %s", (self.transData[self.rows[0].row()][0],)) + meta = self.pg.fetchall()[0][0] + meta = json.dumps(meta) + + # 修改描述 + meta = json.loads(meta) + meta["description"] = descriptionLine.text() + meta = json.dumps(meta) + + + # 修改数据, 使用JSONB + self.pg.execute("UPDATE transaction SET time = %s, amount = %s, meta = %s WHERE t_id = %s",\ + (time, amountLine.text(), meta, self.transData[self.rows[0].row()][0],)) + + # 刷新表格 + self.selected() + + except Exception as e: + print(e) + QMessageBox.critical(self, 'Error', str(e)) + else: + return + + + + + + + + + From 917e08cb8a5e2b2a6087b2a16f053799269e38b9 Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 4 Jun 2023 14:10:51 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E6=94=B9=E5=8F=98=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/budget/_mw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/budget/_mw.py b/src/budget/_mw.py index 0cd12b4..41352c2 100644 --- a/src/budget/_mw.py +++ b/src/budget/_mw.py @@ -9,7 +9,7 @@ from ._stat import StatTab def initUI(self): self.setWindowTitle('budget') - self.setMinimumSize(800, 400) + self.setMinimumSize(800, 600) self.pg = PostgresTab() self.categoryTab = CategoryTab(self) From 4ddb661f0e019a09b8581cfcbc30ab1b61d7a7df Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 4 Jun 2023 14:11:09 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=E7=BB=9F=E8=AE=A1=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/budget/_stat.py | 71 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/budget/_stat.py b/src/budget/_stat.py index 8447ec3..1dd765b 100644 --- a/src/budget/_stat.py +++ b/src/budget/_stat.py @@ -1,7 +1,9 @@ from PyQt6.QtWidgets import * +from PyQt6.QtCharts import * from ._tab import TabPage from ._pg import PostgresTab from PyQt6.QtGui import QDoubleValidator +import datetime import json class StatTab(TabPage): @@ -9,10 +11,73 @@ class StatTab(TabPage): super().__init__() self.initUI() self.pg = parent.pg - self.rows = [] def initUI(self): + # 按钮 + self.outButton = QPushButton('Expense') + self.inButton = QPushButton('Income') + buttonLayout = QHBoxLayout() + buttonLayout.addWidget(self.outButton) + buttonLayout.addWidget(self.inButton) + + # 饼状图 + self.chart = QChart() + self.chart.setTitle('Month Statistics') + self.chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations) + chartLayout = QVBoxLayout() + chartLayout.addWidget(QChartView(self.chart)) + + leftLayout = QVBoxLayout() + leftLayout.addLayout(buttonLayout) + leftLayout.addLayout(chartLayout) + + # 日历控件 + self.calendar = QCalendarWidget() + self.calendar.setGridVisible(True) + # 日历点击事件 + self.calendar.clicked.connect(self.onCalendarClicked) + # 切换月份事件 + self.calendar.currentPageChanged.connect(self.onCalendarPageChanged) + + calenderLayout = QHBoxLayout() + calenderLayout.addWidget(self.calendar) + + statLayout = QHBoxLayout() + statLayout.addLayout(leftLayout) + statLayout.addLayout(calenderLayout) + self.setLayout(statLayout) + + + + def onCalendarClicked(self, date): pass - def onXXXClicked(self): - pass + + def onCalendarPageChanged(self, year, month): + print(year, month) + + # 合计分类的交易量 + self.pg.execute("SELECT c_id, sum(amount)::numeric::float8 FROM transaction WHERE c_id IS NOT NULL and \ + time BETWEEN %s AND %s GROUP BY c_id ORDER BY c_id", \ + (datetime.date(year, month, 1), datetime.date(year, month+1, 1),)) + self.statData = self.pg.fetchall() + print(self.statData) + + # 获取此月所有交易类别 + self.pg.execute("SELECT c_id, meta->>'name' FROM category \ + WHERE c_id in (SELECT c_id FROM transaction WHERE time between %s and %s GROUP BY c_id) \ + ORDER BY c_id", \ + (datetime.date(year, month, 1), datetime.date(year, month+1, 1),)) + self.categoryData = self.pg.fetchall() + print(self.categoryData) + + # 填充饼状图 + self.chart.removeAllSeries() + series = QPieSeries() + for i in range(len(self.statData)): + series.append(self.categoryData[i][1], self.statData[i][1]) + self.chart.addSeries(series) + + def selected(self): + # 刷新图表 + self.onCalendarPageChanged(self.calendar.yearShown(), self.calendar.monthShown()) From de7bd7f8f24796267600c1f69d670b569afbd59c Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 4 Jun 2023 14:26:07 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E8=B4=9F=E5=80=BC=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/budget/_hook.py | 2 -- src/budget/_trans.py | 10 ++++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) delete mode 100644 src/budget/_hook.py diff --git a/src/budget/_hook.py b/src/budget/_hook.py deleted file mode 100644 index 60e2bc6..0000000 --- a/src/budget/_hook.py +++ /dev/null @@ -1,2 +0,0 @@ -from PyQt6.QtWidgets import * -from PyQt6.QtCore import * diff --git a/src/budget/_trans.py b/src/budget/_trans.py index 693f4af..a4b2453 100644 --- a/src/budget/_trans.py +++ b/src/budget/_trans.py @@ -139,8 +139,14 @@ class TransTab(TabPage): amountLabel = QLabel("Amount:") amountLine = QLineEdit() num = self.transData[self.rows[0].row()][5] - # 去掉¥符号 - num = num[1:] + # 去掉¥符号,考虑负值 + if num[0] == '-': + num = num[2:] + num = '-' + num + else: + num = num[1:] + + amountLine.setText(num) # 只允许输入两位小数 amountLine.setValidator(QDoubleValidator(0.00, 999999999.99, 2)) From 6efb61ce26de7dcba5f895669e0c49020558f9ae Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 4 Jun 2023 14:30:03 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E8=A1=A8=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/budget/_category.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/budget/_category.py b/src/budget/_category.py index 82c886d..ee4d8cc 100644 --- a/src/budget/_category.py +++ b/src/budget/_category.py @@ -27,9 +27,9 @@ class CategoryTab(TabPage): topLayout.addWidget(self.categoryAddButton) # 创建表格 - self.accountTable = QTableWidget() + self.categoryTable = QTableWidget() tableLayout = QVBoxLayout() - tableLayout.addWidget(self.accountTable) + tableLayout.addWidget(self.categoryTable) # 应用布局 categoryLayout = QVBoxLayout()