基于Python開發(fā)一個(gè)有趣的工作時(shí)長計(jì)算器
概述
隨著遠(yuǎn)程辦公和彈性工作制的興起,個(gè)人及團(tuán)隊(duì)對于工作時(shí)長的準(zhǔn)確統(tǒng)計(jì)需求日益增長。雖然市面上有眾多復(fù)雜的考勤軟件,但對于簡單的時(shí)間計(jì)算需求,一個(gè)輕量級且界面友好的桌面應(yīng)用更具實(shí)用性和便利性。
本文介紹的“工作時(shí)長計(jì)算器”基于Python的PyQt5庫開發(fā),體積小巧,界面簡潔,支持用戶輸入上下班時(shí)間,一鍵計(jì)算出當(dāng)天工作時(shí)長,并可將結(jié)果復(fù)制到剪貼板,方便粘貼到日報(bào)、考勤系統(tǒng)或聊天工具中。
功能介紹
輸入上下班時(shí)間(HH:MM格式)
自動(dòng)計(jì)算并顯示工作時(shí)長,支持跨天工作時(shí)段
復(fù)制工作時(shí)長到剪貼板,一鍵分享
窗口置頂功能,方便隨時(shí)查看和操作
友好的錯(cuò)誤提示,避免無效時(shí)間格式輸入
自定義窗口圖標(biāo)與樣式美化,提升用戶體驗(yàn)
界面展示
1. 主界面
圖1:工作時(shí)長計(jì)算器主界面,簡潔明了,支持鍵盤輸入與按鈕操作
2. 計(jì)算結(jié)果顯示與復(fù)制反饋
圖2:計(jì)算完成后顯示時(shí)長,點(diǎn)擊復(fù)制按鈕彈出提示
軟件使用步驟說明
啟動(dòng)程序:運(yùn)行python work_time_calculator.py
輸入上班時(shí)間:如08:30
輸入下班時(shí)間:如17:45
點(diǎn)擊“計(jì)算工作時(shí)長”按鈕,顯示工作時(shí)長,例如08:15
點(diǎn)擊“復(fù)制時(shí)長”按鈕,將結(jié)果復(fù)制到剪貼板,方便粘貼
勾選“窗口置頂”,保持程序界面在最前端
如輸入格式錯(cuò)誤,彈出錯(cuò)誤提示框,請按提示修改時(shí)間格式
代碼詳解
1.窗口初始化與布局
class WorkTimeCalculator(QWidget): def __init__(self): super().__init__() self.setWindowTitle("工作時(shí)長計(jì)算器") self.setFixedSize(320, 380) # 設(shè)置窗口圖標(biāo) icon_path = self.resource_path("time.ico") self.setWindowIcon(QIcon(icon_path)) # 窗口置頂屬性 self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.duration_str = "" self.init_ui()
- QWidget是PyQt中最基礎(chǔ)的窗口類。
- 固定窗口大小,保證UI布局一致性。
- 使用自定義圖標(biāo)美化程序。
- 通過Qt.WindowStaysOnTopHint保持窗口置頂。
UI組件布局采用QVBoxLayout垂直堆疊控件,樣式使用QFont和setStyleSheet增強(qiáng)視覺體驗(yàn)。
2.工作時(shí)長計(jì)算核心邏輯
def calculate_time(self): start_text = self.input_start.text().strip() end_text = self.input_end.text().strip() try: start_time = datetime.strptime(start_text, "%H:%M") end_time = datetime.strptime(end_text, "%H:%M") if end_time < start_time: end_time = end_time.replace(day=start_time.day + 1) duration = end_time - start_time total_minutes = duration.seconds // 60 hours = total_minutes // 60 minutes = total_minutes % 60 self.duration_str = f"{hours:02}:{minutes:02}" self.result_label.setText(f"?? 工作時(shí)長:{self.duration_str}") except ValueError: QMessageBox.warning(self, "? 錯(cuò)誤", "請輸入有效時(shí)間格式,如 09:00")
使用datetime.strptime解析輸入時(shí)間。
處理跨天工作(如夜班,結(jié)束時(shí)間小于開始時(shí)間時(shí),自動(dòng)視為第二天)。
計(jì)算時(shí)間差,轉(zhuǎn)換成小時(shí)和分鐘。
結(jié)果格式化為HH:MM,更新界面標(biāo)簽顯示。
異常處理避免程序崩潰,彈出錯(cuò)誤提示框。
3.剪貼板復(fù)制與狀態(tài)提示
def copy_duration(self): if self.duration_str: QApplication.clipboard().setText(self.duration_str) self.show_status_message(f"?? 時(shí)長 {self.duration_str} 已復(fù)制到剪貼板", 1200) else: QMessageBox.warning(self, "?? 無數(shù)據(jù)", "請先計(jì)算工作時(shí)長") def show_status_message(self, message, timeout=1000): self.status_label.setText(message) self.status_label.setVisible(True) QTimer.singleShot(timeout, lambda: self.status_label.setVisible(False))
復(fù)制時(shí)長字符串到系統(tǒng)剪貼板。
使用狀態(tài)欄顯示短暫提示,提升用戶交互體驗(yàn)。
未計(jì)算前復(fù)制操作給出警告提示。
4.窗口置頂功能
def toggle_topmost(self, state): if state == Qt.Checked: self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) else: self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint) self.show()
通過QCheckBox切換窗口置頂屬性。
動(dòng)態(tài)刷新窗口狀態(tài),確保設(shè)置生效。
源碼下載
import sys import os from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QMessageBox, QCheckBox ) from PyQt5.QtGui import QFont, QIcon from PyQt5.QtCore import Qt, QTimer from datetime import datetime class WorkTimeCalculator(QWidget): def __init__(self): super().__init__() self.setWindowTitle("工作時(shí)長計(jì)算器") self.setFixedSize(320, 380) # 設(shè)置窗口圖標(biāo) icon_path = self.resource_path("time.ico") self.setWindowIcon(QIcon(icon_path)) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.duration_str = "" self.init_ui() def init_ui(self): font = QFont("Arial", 12) self.label_start = QLabel("????? 上班時(shí)間 (HH:MM):") self.label_start.setFont(font) self.input_start = QLineEdit() self.input_start.setPlaceholderText("如:08:30") self.input_start.setFont(font) self.input_start.setStyleSheet(""" QLineEdit { border: 2px solid #ccc; border-radius: 10px; padding: 6px 10px; } """) self.label_end = QLabel("?? 下班時(shí)間 (HH:MM):") self.label_end.setFont(font) self.input_end = QLineEdit() self.input_end.setPlaceholderText("如:17:45") self.input_end.setFont(font) self.input_end.setStyleSheet(""" QLineEdit { border: 2px solid #ccc; border-radius: 10px; padding: 6px 10px; } """) self.button_calc = QPushButton("? 計(jì)算工作時(shí)長") self.button_calc.setFont(font) self.button_calc.setStyleSheet(""" QPushButton { background-color: #4CAF50; color: white; border: none; border-radius: 10px; padding: 8px; } QPushButton:hover { background-color: #45a049; } QPushButton:pressed { background-color: #3e8e41; } """) self.button_calc.clicked.connect(self.calculate_time) self.result_label = QLabel("?? 工作時(shí)長:--:--") self.result_label.setFont(QFont("Arial", 13, QFont.Bold)) self.copy_button = QPushButton("?? 復(fù)制時(shí)長") self.copy_button.setFont(font) self.copy_button.setStyleSheet(""" QPushButton { background-color: #2196F3; color: white; border: none; border-radius: 10px; padding: 8px; } QPushButton:hover { background-color: #1e88e5; } QPushButton:pressed { background-color: #1976d2; } """) self.copy_button.clicked.connect(self.copy_duration) self.checkbox_topmost = QCheckBox("?? 窗口置頂") self.checkbox_topmost.setFont(font) self.checkbox_topmost.setChecked(True) self.checkbox_topmost.stateChanged.connect(self.toggle_topmost) self.status_label = QLabel("") self.status_label.setFont(QFont("Arial", 10)) self.status_label.setStyleSheet("color: white; background-color: #444; padding: 4px; border-radius: 4px;") self.status_label.setAlignment(Qt.AlignCenter) self.status_label.setVisible(False) layout = QVBoxLayout() layout.setSpacing(8) layout.setContentsMargins(16, 16, 16, 16) layout.addWidget(self.label_start) layout.addWidget(self.input_start) layout.addWidget(self.label_end) layout.addWidget(self.input_end) layout.addWidget(self.button_calc) layout.addWidget(self.result_label) layout.addWidget(self.copy_button) layout.addWidget(self.checkbox_topmost) layout.addWidget(self.status_label) self.setLayout(layout) def calculate_time(self): start_text = self.input_start.text().strip() end_text = self.input_end.text().strip() try: start_time = datetime.strptime(start_text, "%H:%M") end_time = datetime.strptime(end_text, "%H:%M") if end_time < start_time: end_time = end_time.replace(day=start_time.day + 1) duration = end_time - start_time total_minutes = duration.seconds // 60 hours = total_minutes // 60 minutes = total_minutes % 60 self.duration_str = f"{hours:02}:{minutes:02}" self.result_label.setText(f"?? 工作時(shí)長:{self.duration_str}") except ValueError: QMessageBox.warning(self, "? 錯(cuò)誤", "請輸入有效時(shí)間格式,如 09:00") def copy_duration(self): if self.duration_str: QApplication.clipboard().setText(self.duration_str) self.show_status_message(f"?? 時(shí)長 {self.duration_str} 已復(fù)制到剪貼板", 1200) else: QMessageBox.warning(self, "?? 無數(shù)據(jù)", "請先計(jì)算工作時(shí)長") def show_status_message(self, message, timeout=1000): self.status_label.setText(message) self.status_label.setVisible(True) QTimer.singleShot(timeout, lambda: self.status_label.setVisible(False)) def toggle_topmost(self, state): if state == Qt.Checked: self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) else: self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint) self.show() def resource_path(self, relative_path): """解決打包后資源路徑問題""" if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, relative_path) return os.path.join(os.path.abspath("."), relative_path) if __name__ == "__main__": app = QApplication(sys.argv) app.setStyle("Fusion") window = WorkTimeCalculator() window.show() sys.exit(app.exec_())
總結(jié)與展望
本文詳細(xì)介紹了基于PyQt5的“工作時(shí)長計(jì)算器”的開發(fā)過程,涵蓋了窗口設(shè)計(jì)、時(shí)間處理邏輯、交互細(xì)節(jié)及用戶體驗(yàn)優(yōu)化。該工具簡單實(shí)用,適合日常辦公人員快速統(tǒng)計(jì)工作時(shí)長。
未來可以拓展的功能有:
- 支持批量導(dǎo)入多天時(shí)間記錄,自動(dòng)生成日報(bào)
- 增加午休、加班等特殊時(shí)段計(jì)算支持
- 導(dǎo)出統(tǒng)計(jì)報(bào)表(Excel、PDF等格式)
- 美化UI,支持多語言切換和主題模式
到此這篇關(guān)于基于Python開發(fā)一個(gè)有趣的工作時(shí)長計(jì)算器的文章就介紹到這了,更多相關(guān)Python工作時(shí)長計(jì)算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python遠(yuǎn)程控制Windows服務(wù)器的方法詳解
在很多企業(yè)會(huì)使用閑置的 Windows 機(jī)器作為臨時(shí)服務(wù)器,有時(shí)候我們想遠(yuǎn)程調(diào)用里面的程序或查看日志文件。本文分享了利用Python遠(yuǎn)程控制Windows服務(wù)器的方法,感興趣的可以學(xué)習(xí)一下2022-05-05python通過pil將圖片轉(zhuǎn)換成黑白效果的方法
這篇文章主要介紹了python通過pil將圖片轉(zhuǎn)換成黑白效果的方法,實(shí)例分析了Python中pil庫的使用技巧,需要的朋友可以參考下2015-03-03Python實(shí)現(xiàn)執(zhí)行Shell命令并獲取輸出
這篇文章主要介紹了如何借助?os.system()?從?Python?腳本執(zhí)行?cmd?命令,以及如何借助?Python?中的?subprocess?模塊以更簡單的方式從腳本執(zhí)行?cmd?命令,感興趣的小伙伴可以了解下2023-10-10Python字符串的字符轉(zhuǎn)換、字符串劈分、字符串合并問題分析
這篇文章主要介紹了Python字符串的字符轉(zhuǎn)換、字符串劈分、字符串合并,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-0310分鐘教你用Python實(shí)現(xiàn)微信自動(dòng)回復(fù)功能
今天,我們就來用Python實(shí)現(xiàn)微信的自動(dòng)回復(fù)功能吧,并且把接收到的消息統(tǒng)一發(fā)送到文件助手里面,方便統(tǒng)一查看。感興趣的朋友跟隨小編一起看看吧2018-11-11Kears+Opencv實(shí)現(xiàn)簡單人臉識別
這篇文章主要為大家詳細(xì)介紹了Kears+Opencv實(shí)現(xiàn)簡單人臉識別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08