import sys
import winsound
from PyQt5.QtCore import QTime, QTimer, QDateTime, Qt
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QSizePolicy, QVBoxLayout, QMessageBox, QStackedWidget, QHBoxLayout, \
QLineEdit, QComboBox, QTableWidget, QDateTimeEdit, QTimeEdit, QSpinBox, QStatusBar, QLabel, QPushButton, \
QAbstractItemView, QHeaderView, QTableWidgetItem, QApplication
class MainWindow(QWidget):
def __init__(self):
super(QWidget, self).__init__()
# 设置窗口标题
self.title = '倒计时 by:chinay2023'
self.setWindowTitle(self.title)
# 设置窗口图标
self.setWindowIcon(QIcon('时间.png'))
# 获取屏幕的宽度和高度
screen = QDesktopWidget().screenGeometry()
self.screen_width = screen.width()
screen_height = screen.height()
# 设置窗口的宽度和高度
self.window_width = 1024
window_height = 576
# 计算窗口的左边距和顶边距
left_margin = int(self.screen_width / 2 - self.window_width / 2)
top_margin = int(screen_height / 2 - window_height / 2)
# 设置窗口左边距、顶边距、宽度、高度
self.setGeometry(left_margin, top_margin, self.window_width, window_height)
self.w_layout = QVBoxLayout()
self.stacked_widget = QStackedWidget()
self.msg = QMessageBox()
self.top_layout = QHBoxLayout()
self.title_line = QLineEdit()
self.type_combobox = QComboBox()
self.data_table = QTableWidget()
self.datetime_text = QDateTimeEdit()
self.time_text = QTimeEdit()
self.q_time = QTime()
self.q_time.setHMS(0, 0, 10)
self.sp = QSpinBox()
self.statusbar = QStatusBar()
self.create_component()
timer = QTimer(self)
timer.timeout.connect(self.go_time)
timer.start(1000)
def create_component(self):
try:
title_label = QLabel('标题')
title_label.setMaximumWidth(60)
self.top_layout.addWidget(title_label)
self.title_line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.top_layout.addWidget(self.title_line, 1)
self.type_combobox.setMaximumWidth(200)
self.type_combobox.addItems(['剩余时间', '到期时间'])
self.type_combobox.setMaximumWidth(75)
self.type_combobox.currentIndexChanged.connect(self.type_select)
self.top_layout.addWidget(self.type_combobox)
self.time_text.setMaximumWidth(200)
self.time_text.setDisplayFormat("HH:mm:ss") # 格式化显示时间
self.time_text.setMinimumWidth(72)
self.time_text.setMaximumWidth(72)
self.time_text.setMinimumTime(self.q_time) # 删除日期时间框最小时间
self.stacked_widget.addWidget(self.time_text)
self.datetime_text.setDisplayFormat("yyyy-MM-dd HH:mm:ss") # 格式化显示时间
self.datetime_text.setMinimumWidth(138)
self.datetime_text.setMaximumWidth(138)
self.stacked_widget.addWidget(self.datetime_text)
self.stacked_widget.setMaximumWidth(self.time_text.width())
self.top_layout.addWidget(self.stacked_widget, 1)
self.top_layout.addWidget(QLabel('提前'))
self.sp.setValue(10)
self.top_layout.addWidget(self.sp)
self.top_layout.addWidget(QLabel('秒提醒'))
add_btn = QPushButton('添加')
add_btn.setMaximumWidth(60)
add_btn.clicked.connect(self.add_time)
self.top_layout.addWidget(add_btn)
edit_btn = QPushButton('修改时间')
edit_btn.setMaximumWidth(60)
edit_btn.clicked.connect(self.edit_time)
self.top_layout.addWidget(edit_btn)
del_btn = QPushButton('删除')
del_btn.setMaximumWidth(60)
del_btn.clicked.connect(self.del_time)
self.top_layout.addWidget(del_btn)
self.w_layout.addLayout(self.top_layout)
self.data_table.setColumnCount(3) # 设置表格为3列
self.data_table.setHorizontalHeaderLabels(['标题', '到期时间', '剩余时间']) # 设置表格3列的标题
self.data_table.setShowGrid(True) # 设置显示表格线
self.data_table.verticalHeader().setVisible(False) # 设置行号不可见
self.data_table.setEditTriggers(QAbstractItemView.NoEditTriggers) # 设置表格为不可编辑
self.data_table.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置整行选中
self.data_table.setSelectionMode(QAbstractItemView.SingleSelection) # 设置选择模式为只能选中一行
self.data_table.setColumnWidth(1, 160)
self.data_table.setColumnWidth(2, 160)
self.data_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
self.w_layout.addWidget(self.data_table, 1)
self.w_layout.addWidget(self.statusbar)
self.setLayout(self.w_layout)
except BaseException as e:
print(e)
def type_select(self, index):
self.stacked_widget.setCurrentIndex(index)
if index == 0:
self.stacked_widget.setMaximumWidth(self.time_text.width())
self.time_text.setMinimumTime(self.q_time)
else:
self.stacked_widget.setMaximumWidth(self.datetime_text.width())
self.datetime_text.setMinimumDateTime(QDateTime.currentDateTime().addSecs(10))
def mousePressEvent(self, event):
# 点击QTableWidget控件外部时取消选中的行
if event.button() == Qt.LeftButton and not self.data_table.rect().contains(event.pos()):
self.data_table.clearSelection()
def del_time(self):
if self.data_table.rowCount() > 0:
items = self.data_table.selectedIndexes()
if len(items) > 0:
self.data_table.removeRow(items[0].row())
else:
self.msg.information(self, '提示', '至少选中一行', QMessageBox.Ok)
else:
self.msg.information(self, '提示', '当前表中没有数据', QMessageBox.Ok)
def edit_time(self):
items = self.data_table.selectedIndexes()
if len(items) > 0:
index = items[0].row()
datetime_item = QTableWidgetItem()
datetime_item.setTextAlignment(Qt.AlignCenter)
datetime_text = self.get_datetime_value()
if QDateTime.fromString(datetime_text.text(), 'yyyy-MM-dd HH:mm:ss') <= QDateTime.currentDateTime().addSecs(
10):
self.msg.warning(self, '提示', '到期时间至少大于当前时间10秒以上', QMessageBox.Ok)
return
self.data_table.setItem(index, 1, datetime_text)
# 对第二列进行升序排序
self.data_table.sortItems(1)
def add_time(self):
title = self.title_line.text().strip()
if title == '':
return self.msg.warning(self, '提示', '标题不能为空', QMessageBox.Ok)
matching_items = self.data_table.findItems(title, Qt.MatchExactly)
for item in matching_items:
if item.column() == 0:
return self.msg.warning(self, '提示', '已有相同标题', QMessageBox.Ok)
datetime_text = self.get_datetime_value()
if datetime_text.text() <= QDateTime.currentDateTime().addSecs(10).toString('yyyy-MM-dd HH:mm:ss'):
return self.msg.warning(self, '提示', '到期时间至少大于当前时间10秒以上', QMessageBox.Ok)
row = self.data_table.rowCount()
self.data_table.setRowCount(row + 1)
title_item = QTableWidgetItem(title)
self.data_table.setItem(row, 0, title_item)
self.data_table.setItem(row, 1, datetime_text)
self.data_table.sortItems(1)
def get_datetime_value(self):
type_index = self.type_combobox.currentIndex()
datetime_item = QTableWidgetItem()
datetime_item.setTextAlignment(Qt.AlignCenter)
if type_index == 0:
time = self.time_text.time()
datetime = QDateTime.currentDateTime()
add_time = (time.hour() * 60 + time.minute()) * 60 + time.second()
e_datetime = datetime.addSecs(add_time)
datetime_item.setText(e_datetime.toString('yyyy-MM-dd HH:mm:ss'))
else:
datetime_item.setText(self.datetime_text.text())
return datetime_item
def go_time(self):
if self.data_table.rowCount() > 0:
timer = QDateTime.currentDateTime()
row = self.data_table.rowCount()
self.statusbar.showMessage('当前时间:' + timer.toString('yyyy-MM-dd HH:mm:ss'))
sp_time = self.sp.value()
if row > 0:
for i in range(row):
dd = self.data_table.item(i, 1).text()
dt = QDateTime.fromString(dd, 'yyyy-MM-dd HH:mm:ss')
seconds = timer.secsTo(dt)
if seconds < 0:
continue
color = QColor(255, 255, 255)
if seconds > 0:
if sp_time >= seconds > 0:
color.setRgb(255, 0, 0)
winsound.Beep(2222, 111) # 主板蜂鸣器
item = QTableWidgetItem(f"{seconds // 3600:02d}:{(seconds % 3600) // 60:02d}:{seconds % 60:02d}")
item.setBackground(color)
item.setTextAlignment(Qt.AlignCenter)
self.data_table.setItem(i, 2, item)
else:
color.setRgb(0, 255, 0)
item = QTableWidgetItem("倒计时结束")
item.setBackground(color)
item.setTextAlignment(Qt.AlignCenter)
self.data_table.setItem(i, 2, item)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.resize(650, 400)
window.show()
sys.exit(app.exec_())