吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

python日常記賬本源代碼

汽車電子技術 ? 來源:Python代碼大全 ? 作者:Python代碼狂人 ? 2023-02-24 09:54 ? 次閱讀

python日常記賬本源代碼,基于PySide6(Qt for Python 6)的賬本,界面簡潔、功能強大,支持保存文件、快速查詢、繪制圖表等,是平時記賬的不錯選擇。賬目查詢、賬本編輯、添加/刪除、撤銷/重做、統計數據、生成圖表。

poYBAGP4GFeADw76AABXQLMlXRk378.png

pYYBAGP4GGiAaPo5AAELzN41XNY945.png

pYYBAGP4GHyAdYuvAABR6HNqPFM498.png

pYYBAGP4GIaAWPbfAAEGRDmVkHU033.png

main.py

import sys
from bisect import insort_right
from functools import partial
from os.path import basename
from webbrowser import open_new_tab

from PySide6.QtWidgets import *
from PySide6.QtCore import Slot, QDate
from PySide6.QtGui import QStandardItem, QStandardItemModel

from api import ApiError, openFile, query, saveFile
from dlgAdd import dlgAdd
from dlgCharts import dlgCharts
from dlgSettings import dlgSettings
from ui_dlgHelp import Ui_Dialog as Ui_dlgHelp
from ui_MainWindow import Ui_MainWindow

# Version info
VERSION = '1.2.1'
CHANNEL = 'stable'
BUILD_DATE = '2022-08-25'
FULL_VERSION = f'{VERSION}-{CHANNEL} ({BUILD_DATE}) on {sys.platform}'

app = QApplication(sys.argv)

class AccountBookMainWindow(QMainWindow):
    version_str = '賬本 ' + VERSION
    unsaved_tip = '*'
    SUPPORTED_FILTERS = '賬本文件(*.abf);;文本文件(*.txt);;所有文件(*.*)'

    def __init__(self, parent=None):
        # Initialize window
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle('賬本 ' + VERSION)
        self.labStatus = QLabel(self)
        self.ui.statusBar.addWidget(self.labStatus)

        # Initialize table
        self.model = QStandardItemModel(0, 4, self)
        self.model.setHorizontalHeaderLabels(['日期', '事項', '金額', '備注'])
        self.ui.table.setModel(self.model)
        self.ui.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.__data = []
        self.on_actFile_New_triggered()
        self.ui.actEdit_Remove.setEnabled(False)

        # Connect slots
        self.ui.table.selectionModel().selectionChanged.connect(self.__selectionChanged)
        self.model.itemChanged.connect(self.__itemChanged)

    def __updateTable(self, data):
        self.model.itemChanged.disconnect(self.__itemChanged)
        self.model.setRowCount(len(data))
        for row in range(len(data)):
            for col in range(len(data[row])):
                self.model.setItem(row, col, QStandardItem(data[row][col]))
        self.model.itemChanged.connect(self.__itemChanged)

    def __openFile(self, filename):
        try:
            self.__data = openFile(filename)
        except IOError:
            QMessageBox.critical(self, '錯誤', '文件打開失敗。請稍后再試。')
        except ApiError:
            QMessageBox.critical(self, '錯誤', '文件格式錯誤。請檢查文件完整性。')
        except Exception as e:
            QMessageBox.critical(self, '錯誤', '未知錯誤:' + str(e.with_traceback()))
        else:
            self.ui.searchEdit.clear()
            self.__key = ''
            self.__updateTable(self.__data)
            self.labStatus.setText(filename)
            self.setWindowTitle(self.version_str)
            self.__filename = filename

    def __saveFile(self, filename):
        try:
            saveFile(filename, self.__data)
        except IOError:
            QMessageBox.critical(self, '錯誤', '文件保存錯誤。請稍后再試。')
        except Exception as e:
            QMessageBox.critical(self, '錯誤', '未知錯誤:' + str(e.with_traceback()))
        else:
            self.labStatus.setText('保存成功:' + filename)
            self.setWindowTitle(self.version_str)
            self.__filename = filename

    @Slot()
    def on_actFile_New_triggered(self):
        self.__filename = self.__key = ''
        self.setWindowTitle(self.unsaved_tip + self.version_str)
        self.labStatus.setText('新文件')
        self.model.setRowCount(0)
        self.__data.clear()

    @Slot()
    def on_actFile_Open_triggered(self):
        filename, _ = QFileDialog.getOpenFileName(self, '打開', filter=self.SUPPORTED_FILTERS)
        if filename:
            self.__openFile(filename)

    @Slot()
    def on_actFile_Save_triggered(self):
        if self.__filename:
            self.__saveFile(self.__filename)
        else:
            filename, _ = QFileDialog.getSaveFileName(self, '保存', filter=self.SUPPORTED_FILTERS)
            if filename:
                self.__saveFile(filename)

    @Slot()
    def on_actFile_SaveAs_triggered(self):
        filename, _ = QFileDialog.getSaveFileName(self, '另存為', filter=self.SUPPORTED_FILTERS)
        if filename:
            self.__saveFile(filename)

    @Slot()
    def on_actFile_Settings_triggered(self):
        dlgSettings(self).exec()

    @Slot()
    def on_actHelp_About_triggered(self):
        dialog = QDialog(self)
        ui = Ui_dlgHelp()
        ui.setupUi(dialog)
        for link in (ui.githubLink, ui.giteeLink, ui.licenseLink, ui.readmeLink):
            link.clicked.connect(partial(open_new_tab, link.description()))
        ui.labVersion.setText('版本號:' + FULL_VERSION)
        ui.btnUpdate.clicked.connect(partial(open_new_tab, 'https://github.com/GoodCoder666/AccountBook/releases'))
        dialog.exec()

    @Slot()
    def on_actHelp_AboutQt_triggered(self):
        QMessageBox.aboutQt(self, '關于Qt')

    @Slot()
    def on_actEdit_Add_triggered(self):
        dialog = dlgAdd(self)
        if dialog.exec() == QDialog.Accepted:
            row = dialog.getRow()
            insort_right(self.__data, row)
            self.__updateTable(query(self.__data, self.__key))
            self.setWindowTitle(self.unsaved_tip + self.version_str)

    @Slot()
    def on_actEdit_Remove_triggered(self):
        rows = list(set(map(lambda idx: idx.row(), self.ui.table.selectedIndexes())))
        for row in rows:
            self.__data.remove([self.model.item(row, col).text() for col in range(self.model.columnCount())])
        self.model.itemChanged.disconnect(self.__itemChanged)
        self.model.removeRows(rows[0], len(rows))
        self.model.itemChanged.connect(self.__itemChanged)
        self.setWindowTitle(self.unsaved_tip + self.version_str)

    def __selectionChanged(self):
        self.ui.actEdit_Remove.setEnabled(self.ui.table.selectionModel().hasSelection())

    def __itemChanged(self, item: QStandardItem):
        i, j, new = item.row(), item.column(), item.text()
        if (old := self.__data[i][j]) == new: return
        if j == 0 and not QDate.fromString(new, 'yyyy/MM/dd').isValid():
            QMessageBox.critical(self, '錯誤', '日期格式錯誤。')
            self.model.itemChanged.disconnect(self.__itemChanged)
            item.setText(old)
            self.model.itemChanged.connect(self.__itemChanged)
            return
        row = self.__data.pop(i)
        row[j] = new
        insort_right(self.__data, row)
        self.__updateTable(query(self.__data, self.__key))
        self.setWindowTitle(self.unsaved_tip + self.version_str)

    @Slot()
    def on_searchEdit_textChanged(self):
        self.__key = self.ui.searchEdit.text()
        self.__updateTable(query(self.__data, self.__key))

    @Slot()
    def on_actStat_Show_triggered(self):
        if self.__data:
            dlgCharts(self.__data, self).exec()
        else:
            QMessageBox.information(self, '提示', '請添加數據以使用統計功能。')

    def closeEvent(self, event):
        if not self.windowTitle().startswith(self.unsaved_tip): return
        filename = basename(self.__filename) if self.__filename else '新文件'
        messageBox = QMessageBox(
            parent=self, icon=QMessageBox.Warning, windowTitle='提示',
            text=f'是否要保存對 {filename} 的更改?', informativeText='如果不保存,你的更改將丟失。',
            standardButtons=QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel
        )
        messageBox.setButtonText(QMessageBox.Save, '保存')
        messageBox.setButtonText(QMessageBox.Discard, '不保存')
        messageBox.setButtonText(QMessageBox.Cancel, '取消')
        reply = messageBox.exec()
        if reply == QMessageBox.Save:
            self.on_actFile_Save_triggered()
            event.accept()
        elif reply == QMessageBox.Discard:
            event.accept()
        else:
            event.ignore()

    def dragEnterEvent(self, event):
        event.accept()

    def dropEvent(self, event):
        self.__openFile(event.mimeData().text()[8:]) # [8:] is to get rid of 'file:///'

mainform = AccountBookMainWindow()
mainform.show()

sys.exit(app.exec())

完整程序下載地址:

https://download.csdn.net/download/weixin_42756970/86845889

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 文件
    +關注

    關注

    1

    文章

    570

    瀏覽量

    24820
  • 源代碼
    +關注

    關注

    96

    文章

    2946

    瀏覽量

    66952
  • python
    +關注

    關注

    56

    文章

    4807

    瀏覽量

    85037
收藏 人收藏

    評論

    相關推薦

    選手SHOW|確認過眼神,是我最想要的記賬APP!

    。不僅如此,圈子賬本還考慮到日常記賬習慣,開發出了圈子功能,讓商業伙伴、家庭成員、結伴出行的小伙伴都可以在同一賬本記賬。不僅拉近了彼此之間的
    發表于 07-02 11:48

    uCOS-II-V280是當前UCosII最新版本源代碼

    uCOS-II-V280是當前UCosII最新版本源代碼 /***********************************************************************************************************   &n
    發表于 02-24 14:24 ?0次下載

    Python微服務開發的源代碼合集免費下載

    本文檔的主要內容詳細介紹的是Python微服務開發的源代碼合集免費下載。
    發表于 09-20 08:00 ?3次下載

    區塊高度和記賬本之間有什么關聯

    區塊鏈就像是一個記賬本,而區塊就像是這個記賬本里面的一頁頁記賬紙,區塊高度就是記賬紙的頁碼,當同時出現兩個相同頁碼時就會發生分叉。
    發表于 10-15 14:09 ?608次閱讀

    區塊高度與記賬本頁碼之間的關系分析

    區塊高度顧名思義就是區塊的高度,準確地說是連接在區塊鏈上的塊數。因此想要明白什么是區塊高度,我們得首先搞明白什么是區塊鏈。如果說區塊鏈是記賬本的話,那么一個區塊就像是記賬本的每一頁一樣。
    發表于 10-16 10:20 ?685次閱讀

    python的html基本結構及常見文本標簽源代碼免費下載

    本文檔的主要內容詳細介紹的是python的html基本結構及常見文本標簽源代碼免費下載。
    發表于 12-04 08:00 ?0次下載
    <b class='flag-5'>python</b>的html基本結構及常見文本標簽<b class='flag-5'>源代碼</b>免費下載

    Python深度學習2018的源代碼合集免費下載

    本文檔的主要內容詳細介紹的是Python深度學習2018的源代碼合集免費下載。
    發表于 01-16 10:25 ?70次下載

    python實現目標檢測的源代碼免費下載

    本文檔的主要內容詳細介紹的是python實現目標檢測的源代碼免費下載
    發表于 04-09 08:00 ?6次下載
    <b class='flag-5'>python</b>實現目標檢測的<b class='flag-5'>源代碼</b>免費下載

    python文件讀取的源代碼免費下載

    本文檔的主要內容詳細介紹的是python文件讀取的源代碼免費下載。
    發表于 08-07 17:14 ?20次下載
    <b class='flag-5'>python</b>文件讀取的<b class='flag-5'>源代碼</b>免費下載

    使用Python按行讀文件的源代碼免費下載

    本文檔的主要內容詳細介紹的是使用Python按行讀文件的源代碼免費下載。
    發表于 10-22 17:57 ?12次下載
    使用<b class='flag-5'>Python</b>按行讀文件的<b class='flag-5'>源代碼</b>免費下載

    Python版警察抓小偷游戲源代碼

    Python版警察抓小偷游戲源代碼,有多個難度級別,直接運行game.py,輸入難度級別(1-13)。不同的難度等級對應不同的圖形。
    的頭像 發表于 02-24 09:56 ?1826次閱讀
    <b class='flag-5'>Python</b>版警察抓小偷游戲<b class='flag-5'>源代碼</b>

    Python版超市管理系統源代碼

    Python版超市管理系統源代碼,基于django+mysql安裝步驟
    的頭像 發表于 02-24 09:59 ?1808次閱讀
    <b class='flag-5'>Python</b>版超市管理系統<b class='flag-5'>源代碼</b>

    20個解決日常問題的Python代碼片段!

    在本文中,將分享20 個 Python 代碼片段,以幫助你應對日常編程挑戰。你可能已經知道其中一些片段,但有些其他片段對你來說可能是新的。趕緊使用這些有用的 Python
    的頭像 發表于 03-13 09:40 ?1029次閱讀

    Python編程實戰(源代碼)

    [源代碼]Python編程實戰 妙趣橫生的項目之旅
    發表于 06-06 17:49 ?3次下載

    [源代碼]Python算法詳解

    [源代碼]Python算法詳解[源代碼]Python算法詳解
    發表于 06-06 17:50 ?0次下載
    百家乐在线娱乐可信吗| 24山度数| 至尊百家乐官网qvod| 大发888备用网址大全| 大世界百家乐的玩法技巧和规则| 缅甸百家乐网络赌博解谜| 百家乐官网斗地主炸金花| 山阳县| 网上真钱游戏| 网上娱乐城注册送彩金| 博亿线上娱乐城| 龙博娱乐| 大渡口区| 百家乐官网现实赌场| 盈丰娱乐城| 网上大发扑克| 边城棋牌游戏下载| 大发888手机游戏| 大发888总结经验| 网上真钱斗地主| 大发888在线客服| 大发888游戏论坛| 菲律宾在线游戏| 云梦县| 玉林市| 寿光市| 百家乐官网翻天粤qvod| 狮威百家乐官网娱乐网| 欧洲百家乐官网的玩法技巧和规则 | 威尼斯人娱乐城首存| 大发888娱乐城攻略| 澳门博彩立博| 云鼎娱乐城信誉度| 扬中棋牌游戏中心| 长宁县| 百家乐官网波音平台有假吗| 会理县| 百家乐官网技巧何为百家乐官网之路| 粤港澳百家乐官网娱乐| 百家乐娱乐城新澳博| 死海太阳城酒店|