ETA( ESTIMATED ARRIVAL) 预计到达
计算公式 (v 为速度, sp 为当前进度,st 为总进度,t 为时间):
eta转换为 00:00:00
的形式,当速度为0和完成时,记为 --:--:--
stylesheet (dialog, progressBar)采用渐变 .
这是我原来做的:
import math
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
import ImageLoader
from functions import convert
def PaintWater(self: QtWidgets.QWidget, painter, m_offset, m_waterOffset, percent, w_color):
width, height = self.width(), self.height()
percentage = 1 - percent / 100 # 水波走向:正弦函数 y = A(wx+l) + k
w = 2 * math.pi / width # w 表示 周期,值越大密度越大
A = height * m_waterOffset # A 表示振幅 ,理解为水波的上下振幅
k = height * percentage # k 表示 y 的偏移量,可理解为进度
water1 = QtGui.QPainterPath()
water2 = QtGui.QPainterPath()
water1.moveTo(5, height)
water2.moveTo(5, height)
if m_offset > width / 2:
m_offset = 0
for i in range(5, width - 5):
water1.lineTo(i, A * math.sin(w * i + m_offset) + k)
water2.lineTo(i, A * math.sin(w * i + m_offset + width / 2 * w) + k)
i += 1
water1.lineTo(width - 5, height)
water2.lineTo(width - 5, height)
totalpath = QtGui.QPainterPath()
totalpath.addRect(QtCore.QRectF(5, 5, width - 10, height - 10))
painter.setBrush(QtCore.Qt.gray)
painter.drawRect(self.rect())
painter.save()
painter.setPen(QtCore.Qt.NoPen)
watercolor1 = QtGui.QColor(w_color)
watercolor1.setAlpha(100)
watercolor2 = QtGui.QColor(w_color)
watercolor2.setAlpha(150)
path = totalpath.intersected(water1)
painter.setBrush(watercolor1)
painter.drawPath(path)
path = totalpath.intersected(water2)
painter.setBrush(watercolor2)
painter.drawPath(path)
painter.restore()
class WaterProgressBar(QtWidgets.QWidget):
def __init__(self, parent=None):
super(WaterProgressBar, self).__init__(parent)
self.resize(200, 60)
# 背景填充灰色
self.setAutoFillBackground(True)
p = QtGui.QPalette()
p.setColor(QtGui.QPalette.Background, QtCore.Qt.gray)
self.setPalette(p)
self.bg_color = QtGui.QColor("95BBFF")
self.startTimer(80)
self.m_waterOffset = 0.05
self.m_offset = 50
self.m_border_width = 10
self._percent = 90
self.finished = False
self.__reversed = 100.
def paintEvent(self, event):
# 锯齿状绘画板;
painter = QtGui.QPainter()
painter.begin(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
width, height = self.width(), self.height()
if not self.finished and self._percent == 100:
self.finished = True
if not self.finished:
self.m_offset += 0.6
PaintWater(self, painter, self.m_offset, self.m_waterOffset, self._percent, self.bg_color)
elif self.__reversed > 0.:
self.__reversed -= 3.1
self.m_offset -= 0.6
painter.setBrush(QtGui.QColor(self.bg_color))
painter.drawRect(QtCore.QRectF(0, width / 100 * (100 - self.__reversed), width, height))
PaintWater(self, painter, self.m_offset, self.m_waterOffset, self.__reversed, self.bg_color)
else:
super().paintEvent(event)
m_font = QtGui.QFont()
m_font.setFamily('Microsoft YaHei')
m_font.setPixelSize(int(self.width() / 10))
painter.setPen(QtCore.Qt.white)
painter.setFont(m_font)
painter.drawText(self.rect(), QtCore.Qt.AlignCenter, "{}%".format(self._percent))
painter.end()
class SimpleProgressDialog(QtWidgets.QDialog):
def __init__(self, parent=None, total=100):
super().__init__(parent)
self._startTime = time.time()
self._endTime = None
self._startPos = None
self._tracking = None
self._endPos = None
self.percent = 0
self.progress = 0
self.total = total
self.setObjectName("FileProgress")
self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口背景透明
self.setWindowFlags(Qt.FramelessWindowHint) # 去边框
self.resize(480, 760)
font = QtGui.QFont()
font.setFamily("Consolas")
self.setFont(font)
self.horizontalLayout = QtWidgets.QHBoxLayout(self)
self.horizontalLayout.setObjectName("horizontalLayout")
self.CentralLayoutWidget = QtWidgets.QWidget(self)
self.CentralLayoutWidget.setStyleSheet("#CentralLayoutWidget {\n"
"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, "
"stop:0 rgba(82, 87, 250, 255), stop:1 rgba( "
"245, 140, 107, 255));\n "
"border-radius: 10px; border: 1px solid qlineargradient(spread:pad, "
"x1:0, y1:0, x2:1, y2:1, stop:0 rgba(82, 87, 250, 255), stop:1 rgba("
"245, 140, 107, 255));\n "
"}")
self.CentralLayoutWidget.setObjectName("CentralLayoutWidget")
self.centralLayoutWidget = QtWidgets.QVBoxLayout(self.CentralLayoutWidget)
self.centralLayoutWidget.setObjectName("centralLayoutWidget")
self.closeButton = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.closeButton.setMaximumSize(QtCore.QSize(30, 30))
self.closeButton.setBaseSize(QtCore.QSize(0, 0))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("images/close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.closeButton.setIcon(icon)
self.closeButton.setIconSize(QtCore.QSize(24, 24))
self.closeButton.setObjectName("closeButton")
self.centralLayoutWidget.addWidget(self.closeButton, 0, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.filename_label = QtWidgets.QLabel(self.CentralLayoutWidget)
self.filename_label.setStyleSheet("color: rgb(255, 255, 255);\n"
"font: 11pt \"Consolas\";")
self.filename_label.setScaledContents(False)
self.filename_label.setObjectName("filename_label")
self.centralLayoutWidget.addWidget(self.filename_label, 0, QtCore.Qt.AlignHCenter)
self.icon_label = QtWidgets.QLabel(self.CentralLayoutWidget)
self.icon_label.setMaximumSize(QtCore.QSize(70, 70))
self.icon_label.setScaledContents(True)
self.icon_label.setObjectName("icon_label")
self.centralLayoutWidget.addWidget(self.icon_label, 0, QtCore.Qt.AlignHCenter)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.centralLayoutWidget.addItem(spacerItem)
self.fileLayout = QtWidgets.QHBoxLayout()
self.fileLayout.setObjectName("fileLayout")
self.size_label_tag = QtWidgets.QLabel()
self.size_label_tag.setObjectName("size_label")
self.size_label_tag.setStyleSheet("color: rgb(255, 255, 255);\n"
"font: 11pt \"Consolas\";")
self.fileLayout.addWidget(self.size_label_tag)
self.size_label = QtWidgets.QLabel()
self.size_label.setStyleSheet("color: rgb(255, 255, 0);\n"
"font: 11pt \"Consolas\";")
self.fileLayout.addWidget(self.size_label)
widget = QtWidgets.QWidget()
widget.setLayout(self.fileLayout)
self.centralLayoutWidget.addWidget(widget, 0, QtCore.Qt.AlignHCenter)
self.line = QtWidgets.QFrame(self.CentralLayoutWidget)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.centralLayoutWidget.addWidget(self.line)
self.infoLayout = QtWidgets.QHBoxLayout()
self.infoLayout.setObjectName("infoLayout")
self.progressLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.progressLabel.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(83, 230, 60);")
self.progressLabel.setObjectName("progress")
self.infoLayout.addWidget(self.progressLabel)
self.speedLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.speedLabel.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(255, 255, 0);")
self.speedLabel.setObjectName("speed")
self.infoLayout.addWidget(self.speedLabel)
self.eta = QtWidgets.QLabel(self.CentralLayoutWidget)
self.eta.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(11, 235, 255);")
self.eta.setObjectName("eta")
self.infoLayout.addWidget(self.eta)
self.centralLayoutWidget.addLayout(self.infoLayout)
self.progressbar = QtWidgets.QProgressBar(self.CentralLayoutWidget)
self.progressbar.setMinimum(0)
self.progressbar.setProperty("value", 0)
self.progressbar.setTextVisible(False)
self.progressbar.setInvertedAppearance(False)
self.progressbar.setObjectName("progressbar")
self.centralLayoutWidget.addWidget(self.progressbar)
self.percentLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.percentLabel.setStyleSheet("font: 11pt \"Consolas\";\n"
"color: rgb(0, 85, 255);")
self.percentLabel.setObjectName("percent")
self.centralLayoutWidget.addWidget(self.percentLabel, 0, QtCore.Qt.AlignHCenter)
self.openFile = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.openFile.setMaximumSize(QtCore.QSize(100, 16777215))
self.openFile.setObjectName("openFile")
self.centralLayoutWidget.addWidget(self.openFile, 0, QtCore.Qt.AlignHCenter)
self.openPath = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.openPath.setMaximumSize(QtCore.QSize(100, 16777215))
self.openPath.setObjectName("openFile_2")
self.centralLayoutWidget.addWidget(self.openPath, 0, QtCore.Qt.AlignHCenter)
self.horizontalLayout.addWidget(self.CentralLayoutWidget)
self.closeButton.clicked.connect(self.close)
QtCore.QMetaObject.connectSlotsByName(self)
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("FileProgress", "Dialog"))
self.filename_label.setText(_translate("FileProgress", "{filename}"))
self.progressLabel.setToolTip(_translate("FileProgress", "<html><head/><body><p>当前进度</p></body></html>"))
self.progressLabel.setText(_translate("FileProgress", f"0 / {convert(self.total)}"))
self.speedLabel.setToolTip(_translate("FileProgress", "<html><head/><body><p>速度</p></body></html>"))
self.speedLabel.setWhatsThis(_translate("FileProgress", "<html><head/><body><p><br/></p></body></html>"))
self.speedLabel.setText(_translate("FileProgress", "speed"))
self.eta.setToolTip(_translate("FileProgress",
"<html><head/><body><p><span style=\" font-weight:600; "
"color:#ff0000;\">eta</span><span style=\" color:#000000;\">, 即</span><span "
"style=\" font-weight:600; color:#000000;\">E</span><span style=\" "
"color:#000000;\">stimated </span><span style=\" font-weight:600; "
"color:#000000;\">T</span><span style=\" color:#000000;\">ime of </span><span "
"style=\" font-weight:600; color:#000000;\">A</span><span style=\" "
"color:#000000;\">rrival, </span><span style=\" font-weight:600; "
"color:#000000;\">预计到达时间</span><span style=\" "
"color:#000000;\">.</span></p></body></html>"))
self.eta.setWhatsThis(_translate("FileProgress", "<html><head/><body><p><br/></p></body></html>"))
self.eta.setText(_translate("FileProgress", "eta"))
self.percentLabel.setText(_translate("FileProgress", "0%"))
self.openFile.setText(_translate("FileProgress", "打开文件"))
self.openPath.setText(_translate("FileProgress", "转到目录"))
self.size_label_tag.setText(_translate("FileProgress", "大小:"))
self.size_label.setText(_translate("FileProgress", f"{convert(self.total)}"))
self.progressbar.setRange(0, 0)
self.setWindowOpacity(0.9)
self.progressbar.setStyleSheet("\n"
"#progressbar {\n"
" min-height: 12px;\n"
" max-height: 12px;\n"
" border-radius: 6px;\n"
"}\n"
"#progressbar::chunk {\n"
" border-radius: 6px;\n"
"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, "
f"stop:0 rgba(50, 0, 255, 255), stop:1 rgba({self.percent}, 185, 255, 255));\n "
"}")
self.openFile.setEnabled(False)
def _set_eta(self, _stamp: (int, float)):
if self.is_finished():
if not isinstance(self._endTime, (int, float)):
self._endTime = time.time()
self.eta.setText("total " + str(time.strftime("%H:%M:%S",
time.gmtime(float(self._endTime - self._startTime)))))
else:
if _stamp == 0:
self.eta.setText("eta --:--:--")
else:
self.eta.setText("eta " + str(time.strftime("%H:%M:%S", time.gmtime(float(_stamp)))))
def _set_speed(self, _transfer: int):
self.speedLabel.setText(f"{'total ' if self.is_finished() else str()}{convert(_transfer)}/s")
def _set_progress(self):
if self.is_finished():
self.progressLabel.setText("finished")
else:
self.progressLabel.setText(f"{convert(self.progress)} / {convert(self.total)}")
def mouseMoveEvent(self, e): # re-write mouseMoveEvent
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
self._startPos = QtCore.QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
@QtCore.pyqtSlot(int)
def updateValue(self, length=1):
self.progress += length
if self.progress > self.total:
self.progress = self.total
self.percent = int(round(self.progress / self.total, 2) * 100)
if self.is_finished():
self.openFile.setEnabled(True)
self.progressbar.hide()
self.percentLabel.hide()
self.progressbar.setMaximum(100)
self.progressbar.setValue(self.percent)
self.percentLabel.setText(f"{self.percent}%")
self.valueChangedEvent(length)
self._set_progress()
def is_finished(self) -> bool:
return self.progress == self.total
def valueChangedEvent(self, added):
pass
class ProgressDialog(SimpleProgressDialog):
def __init__(self, total, filename, filepath, time_stamp=None, progress=None, parent=None, x=0, y=0):
super(ProgressDialog, self).__init__(parent, total=total)
self.resize(320, 640)
self.timeStamp = time.time()
self.eta_value = 0
self.speed = 0
self.filename = filename
self.filepath = filepath
self.file = os.path.join(filepath, filename)
self.eta_added_value = 0
self.icon_label.setPixmap(QtGui.QPixmap(ImageLoader.get(filename)))
self.filename_label.setText(filename)
self.openFile.clicked.connect(self.startFile)
self.openPath.clicked.connect(self.startPath)
self.count_eta_timer = QtCore.QTimer(self)
self.count_eta_timer.timeout.connect(self.update)
self.count_eta_timer.start(500)
self.update()
if isinstance(progress, int) and isinstance(progress, (int, float)):
self.already_start(progress, time_stamp)
self.exec_()
def already_start(self, progress: int, time_stamp: (int, float)):
self.progress = progress
self._startTime = time_stamp
def valueChangedEvent(self, added):
self.eta_added_value += added
def startFile(self, *args):
if os.path.isfile(self.file):
os.startfile(self.file)
def startPath(self, *args):
if os.path.isfile(self.filepath):
os.startfile(self.filepath)
def update(self, *args):
super().update(*args)
self._set_eta(self.eta_value)
self._set_speed(self.speed)
if not self.is_finished():
self.speed = self.eta_added_value / (
time.time() - self.timeStamp) if time.time() - self.timeStamp != 0 else 0
self.eta_value = (self.total - self.progress) / self.speed if self.speed != 0 else 0
self.timeStamp = time.time()
else:
self.speed = self.total / (self._endTime - self._startTime)
self.eta_added_value = 0
class FileListWidget(QtWidgets.QListWidget):
class ListWidgetLayout(QtWidgets.QWidget):
def __init__(self, name, total, size, parent=None):
super(FileListWidget.ListWidgetLayout, self).__init__(parent)
self.size = size
self.total = total
self.segment = math.ceil(self.size // self.total)
self.progress = 0
hbox = QtWidgets.QHBoxLayout(self)
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(QtWidgets.QLabel(name + f"\n({convert(self.size)})", self))
progress = QtWidgets.QProgressBar()
progress.setMaximum(total)
progress.setStyleSheet("QProgressBar{\n"
"text-align: center;\n"
'font: 9pt "Consolas";\n'
"}")
vbox.setObjectName("name, speed Info")
hbox.setObjectName("Info and Progress")
progress.setTextVisible(True)
progress.setRange(0, 0)
self.label = QtWidgets.QLabel(self)
self.label.setStyleSheet("color: rgb(60, 112, 255);")
vbox.addWidget(self.label)
self.progressbar = progress
vbox.setSpacing(2)
hbox.addLayout(vbox)
hbox.addWidget(progress)
self.setLayout(hbox)
fonts = QtGui.QFont()
fonts.setFamily("Consolas")
fonts.setPointSize(9)
self.setFont(fonts)
self.label.setFont(fonts)
self.start_time = time.time()
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.timers)
self.timer.start(50)
def timers(self, *args) -> None:
timeit = self.get_time()
if timeit == 0:
return # ZeroDivisionError: integer division or modulo by zero
content = f"{convert(int((self.segment * self.progress) / timeit))}/s ({self.str_time()} 秒)"
self.label.setText(content)
def get_progressbar(self) -> QtWidgets.QProgressBar:
return self.progressbar
def is_finished(self) -> bool:
return bool(self.progress >= self.total)
def update(self) -> None:
if self.progress == 0:
self.progressbar.setMaximum(self.total)
if self.is_finished():
return
self.progress += 1
if self.is_finished():
self.end_time = time.time()
self.progressbar.setValue(self.progress)
def get_total(self) -> int:
return self.total
def get_time(self) -> float:
return getattr(self, "end_time", time.time()) - self.start_time
def str_time(self) -> str:
return "%0.1f" % (self.get_time())
def get_progress(self) -> int:
return self.progress
class ListItem(QtWidgets.QListWidgetItem):
def __init__(self, parent: QtWidgets.QListWidget, icon: QtGui.QIcon, index: int, layout, size=(200, 80)):
super(FileListWidget.ListItem, self).__init__(icon, str(), parent)
self.index_name = index
self.setSizeHint(QtCore.QSize(200, 80))
self.setSizeHint(QtCore.QSize(*size))
parent.addItem(self)
parent.setItemWidget(self, layout)
DOWNLOAD = 0
UPLOAD = 1
def __init__(self, _save_path, parent=None):
self.x, self.y = 0, 0
self.dialog_index = 0
self.dialog = None
self.rightClickedItem = None
self.path = None
self.fpath = None
self.current = ""
super().__init__(parent)
self.setWindowIcon(QtGui.QIcon("images/file.png"))
self.download = QtGui.QIcon("images/download.png")
self.upload = QtGui.QIcon("images/upload.png")
self.LOAD_dict = {self.DOWNLOAD: self.download,
self.UPLOAD: self.upload}
self.save_path = _save_path
self.filedict = {}
self.pathdict = {}
self.namedict = {}
self.infodict = {}
self.setObjectName("FileDisplayWindow")
self.resize(666, 421)
font = QtGui.QFont()
font.setFamily("Consolas")
self.setFont(font)
self.setWindowTitle(QtCore.QCoreApplication.translate("Dialog", "Files"))
self.itemClicked.connect(self.fileClicked)
self.menu = QtWidgets.QMenu(self)
open_file = QtWidgets.QAction(QtGui.QIcon("images/file.png"), '打开文件', self)
open_file.triggered.connect(self.startfile)
self.menu.addAction(open_file)
open_path = QtWidgets.QAction(QtGui.QIcon("images/folder.png"), '打开文件夹', self)
open_path.triggered.connect(self.startpath)
self.menu.addAction(open_path)
QtCore.QMetaObject.connectSlotsByName(self)
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
super().mousePressEvent(event)
if event.button() == QtCore.Qt.RightButton and self.itemAt(event.pos()):
item = self.itemAt(event.pos())
index: int = item.index_name
self.fpath = self.pathdict[index]
self.path = os.path.dirname(self.fpath)
self.menu.exec(event.globalPos())
@QtCore.pyqtSlot(str, int, int, tuple)
def new_file(self, name, total, size, info):
self.activateWindow() # 窗口置顶
index = len(self.filedict)
_type, localfile = info
layout = FileListWidget.ListWidgetLayout(name, total, size)
self.filedict[index] = (layout, size)
self.pathdict[index] = localfile
self.infodict[index] = (total, name, os.path.dirname(localfile), time.time())
item = FileListWidget.ListItem(self, self.LOAD_dict.get(_type, self.UPLOAD), index, layout)
self.show()
@QtCore.pyqtSlot(int)
def update_file(self, index: int):
layout, size = self.filedict[index]
layout: FileListWidget.ListWidgetLayout
layout.update()
if isinstance(self.dialog, ProgressDialog):
if index == self.dialog_index:
self.dialog.updateValue(1)
def fileClicked(self, item: ListItem):
index = item.index_name
self.dialog = ProgressDialog(*self.infodict[index], self.filedict[index][0].get_progress())
self.dialog_index = index
def startfile(self, *args):
if isinstance(self.fpath, str) and os.path.isfile(self.fpath):
os.startfile(self.fpath)
def startpath(self, *args):
if isinstance(self.path, str) and os.path.isdir(self.path):
os.startfile(self.path)
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
super(FileListWidget, self).mouseMoveEvent(event)
self.x, self.y = event.x(), event.y()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
a = FileListWidget(os.path.join(os.path.dirname(os.path.realpath(__file__)), "database", "resource"))
a.new_file("asdf", 1010, 11111, (0, "C:/users/zhnwe/desktop/1.rte"))
a.show()
app.exec_()
现在呢,我有创建了一个类_cSpeed
, 方便在3个类中管理.
class _cSpeed(object):
def __init__(self, total: (int, float) = 100, slot: (QtCore.pyqtSlot, None) = None):
self.__create_time = time.time()
self.__end_time = None
self.__update_value = int()
self.__total_value = total
self.slots = []
self.add_slot(slot)
self.timed_once = time.time()
self.update_once = int()
def add_slot(self, slot: QtCore.pyqtSlot):
if callable(slot):
self.slots.append(slot)
def get_total(self) -> str:
return convert(self.__total_value)
def _count_speed(self) -> float: # once
resp = self.update_once / (time.time() - self.timed_once) if (time.time() - self.timed_once) else 0.
self.update_once = int()
self.timed_once = time.time()
return resp
# return (self.__update_value / self._get_time()) if self._get_time() else 0.
def _round_speed(self, value: int = 2) -> float:
return round(self._count_speed(), value)
def get_speed(self, value: int = 2, exact=False) -> str:
return f"{convert(self._round_speed(value), bool(exact))}/s"
def get_percent(self) -> int:
return int(round(self.__update_value / self.__total_value, 2) * 100)
def update_value(self, value: (int, float) = 1.) -> None:
self.__update_value += value
self.update_once += value
if self.__update_value >= self.__total_value:
self.__update_value = self.__total_value
if self.__end_time is None:
self.__end_time = time.time()
for slot in self.slots:
slot()
def _value(self) -> (float, int):
return self.__update_value
def is_finished(self) -> bool:
return not bool(self._get_over())
def get_progress(self) -> str:
return f"{convert(self.__update_value)} / {convert(self.__total_value)}" \
if self._get_over() else convert(self.__total_value)
def _get_over(self) -> float:
return self.__total_value - self.__update_value
def get_eta(self) -> str:
assert isinstance(self.__total_value, (int, float)), "total value is Incalculable!"
return f'eta {time.strftime("%H:%M:%S", time.gmtime(self._get_over() / self._count_speed())) if self._count_speed() else "--:--:--"}' \
if self._get_over() else \
f'total {time.strftime("%H:%M:%S", time.gmtime(self.__end_time - self.__create_time))}'
def _get_time(self) -> float:
return (self.__end_time if isinstance(self.__end_time, float) else time.time()) - self.__create_time
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'progressbar.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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.
import math
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
import ImageLoader
from functions import convert
class _cSpeed(object):
def __init__(self, total: (int, float) = 100, slot: (QtCore.pyqtSlot, None) = None):
self.__create_time = time.time()
self.__end_time = None
self.__update_value = int()
self.__total_value = total
self.slots = []
self.add_slot(slot)
self.timed_once = time.time()
self.update_once = int()
def add_slot(self, slot: QtCore.pyqtSlot):
if callable(slot):
self.slots.append(slot)
def get_total(self) -> str:
return convert(self.__total_value)
def _count_speed(self) -> float: # once
resp = self.update_once / (time.time() - self.timed_once) if (time.time() - self.timed_once) else 0.
self.update_once = int()
self.timed_once = time.time()
return resp
# return (self.__update_value / self._get_time()) if self._get_time() else 0.
def _round_speed(self, value: int = 2) -> float:
return round(self._count_speed(), value)
def get_speed(self, value: int = 2, exact=False) -> str:
return f"{convert(self._round_speed(value), bool(exact))}/s"
def get_percent(self) -> int:
return int(round(self.__update_value / self.__total_value, 2) * 100)
def update_value(self, value: (int, float) = 1.) -> None:
self.__update_value += value
self.update_once += value
if self.__update_value >= self.__total_value:
self.__update_value = self.__total_value
if self.__end_time is None:
self.__end_time = time.time()
for slot in self.slots:
slot()
def _value(self) -> (float, int):
return self.__update_value
def is_finished(self) -> bool:
return not bool(self._get_over())
def get_progress(self) -> str:
return f"{convert(self.__update_value)} / {convert(self.__total_value)}" \
if self._get_over() else convert(self.__total_value)
def _get_over(self) -> float:
return self.__total_value - self.__update_value
def get_eta(self) -> str:
assert isinstance(self.__total_value, (int, float)), "total value is Incalculable!"
return f'eta {time.strftime("%H:%M:%S", time.gmtime(self._get_over() / self._count_speed())) if self._count_speed() else "--:--:--"}' \
if self._get_over() else \
f'total {time.strftime("%H:%M:%S", time.gmtime(self.__end_time - self.__create_time))}'
def _get_time(self) -> float:
return (self.__end_time if isinstance(self.__end_time, float) else time.time()) - self.__create_time
class WaterProgressBar(QtWidgets.QWidget):
def PaintWater(self: QtWidgets.QWidget, painter, m_offset, m_waterOffset, percent, w_color):
width, height = self.width(), self.height()
percentage = 1 - percent / 100 # 水波走向:正弦函数 y = A(wx+l) + k
w = 2 * math.pi / width # w 表示 周期,值越大密度越大
A = height * m_waterOffset # A 表示振幅 ,理解为水波的上下振幅
k = height * percentage # k 表示 y 的偏移量,可理解为进度
water1 = QtGui.QPainterPath()
water2 = QtGui.QPainterPath()
water1.moveTo(5, height)
water2.moveTo(5, height)
if m_offset > width / 2:
m_offset = 0
for i in range(5, width - 5):
water1.lineTo(i, A * math.sin(w * i + m_offset) + k)
water2.lineTo(i, A * math.sin(w * i + m_offset + width / 2 * w) + k)
i += 1
water1.lineTo(width - 5, height)
water2.lineTo(width - 5, height)
total_path = QtGui.QPainterPath()
total_path.addRect(QtCore.QRectF(5, 5, width - 10, height - 10))
painter.setBrush(QtCore.Qt.gray)
painter.drawRect(self.rect())
painter.save()
painter.setPen(QtCore.Qt.NoPen)
watercolor1 = QtGui.QColor(w_color)
watercolor1.setAlpha(100)
watercolor2 = QtGui.QColor(w_color)
watercolor2.setAlpha(150)
path = total_path.intersected(water1)
painter.setBrush(watercolor1)
painter.drawPath(path)
path = total_path.intersected(water2)
painter.setBrush(watercolor2)
painter.drawPath(path)
painter.restore()
def __init__(self, parent=None):
super(WaterProgressBar, self).__init__(parent)
self.resize(200, 60)
# 背景填充灰色
self.setAutoFillBackground(True)
p = QtGui.QPalette()
p.setColor(QtGui.QPalette.Background, QtCore.Qt.gray)
self.setPalette(p)
self.bg_color = QtGui.QColor("95BBFF")
self.startTimer(80)
self.m_waterOffset = 0.05
self.m_offset = 50
self.m_border_width = 10
self._percent = 90
self.finished = False
self.__reversed = 100.
def paintEvent(self, event):
# 锯齿状绘画板;
painter = QtGui.QPainter()
painter.begin(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
width, height = self.width(), self.height()
if not self.finished and self._percent == 100:
self.finished = True
if not self.finished:
self.m_offset += 0.6
self.PaintWater(self, painter, self.m_offset, self.m_waterOffset, self._percent, self.bg_color)
elif self.__reversed > 0.:
self.__reversed -= 3.1
self.m_offset -= 0.6
painter.setBrush(QtGui.QColor(self.bg_color))
painter.drawRect(QtCore.QRectF(0, width / 100 * (100 - self.__reversed), width, height))
self.PaintWater(self, painter, self.m_offset, self.m_waterOffset, self.__reversed, self.bg_color)
else:
super().paintEvent(event)
m_font = QtGui.QFont()
m_font.setFamily('Microsoft YaHei')
m_font.setPixelSize(int(self.width() / 10))
painter.setPen(QtCore.Qt.white)
painter.setFont(m_font)
painter.drawText(self.rect(), QtCore.Qt.AlignCenter, "{}%".format(self._percent))
painter.end()
class SimpleProgressDialog(QtWidgets.QDialog):
def __init__(self, parent=None, cSpeed: _cSpeed = _cSpeed(100)):
super().__init__(parent)
self._startPos = None
self._tracking = None
self._endPos = None
self.percent = 0
self._cSpeed = cSpeed
self.setObjectName("FileProgress")
self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口背景透明
self.setWindowFlags(Qt.FramelessWindowHint) # 去边框
self.resize(480, 760)
font = QtGui.QFont()
font.setFamily("Consolas")
self.setFont(font)
self.horizontalLayout = QtWidgets.QHBoxLayout(self)
self.horizontalLayout.setObjectName("horizontalLayout")
self.CentralLayoutWidget = QtWidgets.QWidget(self)
self.CentralLayoutWidget.setStyleSheet("#CentralLayoutWidget {\n"
"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, "
"stop:0 rgba(82, 87, 250, 255), stop:1 rgba( "
"245, 140, 107, 255));\n "
"border-radius: 10px; border: 1px solid qlineargradient(spread:pad, "
"x1:0, y1:0, x2:1, y2:1, stop:0 rgba(82, 87, 250, 255), stop:1 rgba("
"245, 140, 107, 255));\n "
"}")
self.CentralLayoutWidget.setObjectName("CentralLayoutWidget")
self.centralLayoutWidget = QtWidgets.QVBoxLayout(self.CentralLayoutWidget)
self.centralLayoutWidget.setObjectName("centralLayoutWidget")
self.closeButton = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.closeButton.setMaximumSize(QtCore.QSize(30, 30))
self.closeButton.setBaseSize(QtCore.QSize(0, 0))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("images/close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.closeButton.setIcon(icon)
self.closeButton.setIconSize(QtCore.QSize(24, 24))
self.closeButton.setObjectName("closeButton")
self.centralLayoutWidget.addWidget(self.closeButton, 0, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.filename_label = QtWidgets.QLabel(self.CentralLayoutWidget)
self.filename_label.setStyleSheet("color: rgb(255, 255, 255);\n"
"font: 11pt \"Consolas\";")
self.filename_label.setScaledContents(False)
self.filename_label.setObjectName("filename_label")
self.centralLayoutWidget.addWidget(self.filename_label, 0, QtCore.Qt.AlignHCenter)
self.icon_label = QtWidgets.QLabel(self.CentralLayoutWidget)
self.icon_label.setMaximumSize(QtCore.QSize(70, 70))
self.icon_label.setScaledContents(True)
self.icon_label.setObjectName("icon_label")
self.centralLayoutWidget.addWidget(self.icon_label, 0, QtCore.Qt.AlignHCenter)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.centralLayoutWidget.addItem(spacerItem)
self.fileLayout = QtWidgets.QHBoxLayout()
self.fileLayout.setObjectName("fileLayout")
self.size_label_tag = QtWidgets.QLabel()
self.size_label_tag.setObjectName("size_label")
self.size_label_tag.setStyleSheet("color: rgb(255, 255, 255);\n"
"font: 11pt \"Consolas\";")
self.fileLayout.addWidget(self.size_label_tag)
self.size_label = QtWidgets.QLabel()
self.size_label.setStyleSheet("color: rgb(255, 255, 0);\n"
"font: 11pt \"Consolas\";")
self.fileLayout.addWidget(self.size_label)
widget = QtWidgets.QWidget()
widget.setLayout(self.fileLayout)
self.centralLayoutWidget.addWidget(widget, 0, QtCore.Qt.AlignHCenter)
self.line = QtWidgets.QFrame(self.CentralLayoutWidget)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.centralLayoutWidget.addWidget(self.line)
self.infoLayout = QtWidgets.QHBoxLayout()
self.infoLayout.setObjectName("infoLayout")
self.progressLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.progressLabel.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(83, 230, 60);")
self.progressLabel.setObjectName("progress")
self.infoLayout.addWidget(self.progressLabel)
self.speedLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.speedLabel.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(255, 255, 0);")
self.speedLabel.setObjectName("speed")
self.infoLayout.addWidget(self.speedLabel)
self.eta = QtWidgets.QLabel(self.CentralLayoutWidget)
self.eta.setStyleSheet("font: 11pt \"Comic Sans MS\";\n"
"color: rgb(11, 235, 255);")
self.eta.setObjectName("eta")
self.infoLayout.addWidget(self.eta)
self.centralLayoutWidget.addLayout(self.infoLayout)
self.progressbar = QtWidgets.QProgressBar(self.CentralLayoutWidget)
self.progressbar.setMinimum(0)
self.progressbar.setProperty("value", 0)
self.progressbar.setTextVisible(False)
self.progressbar.setInvertedAppearance(False)
self.progressbar.setObjectName("progressbar")
self.centralLayoutWidget.addWidget(self.progressbar)
self.percentLabel = QtWidgets.QLabel(self.CentralLayoutWidget)
self.percentLabel.setStyleSheet("font: 11pt \"Consolas\";\n"
"color: rgb(0, 85, 255);")
self.percentLabel.setObjectName("percent")
self.centralLayoutWidget.addWidget(self.percentLabel, 0, QtCore.Qt.AlignHCenter)
self.openFile = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.openFile.setMaximumSize(QtCore.QSize(100, 16777215))
self.openFile.setObjectName("openFile")
self.centralLayoutWidget.addWidget(self.openFile, 0, QtCore.Qt.AlignHCenter)
self.openPath = QtWidgets.QPushButton(self.CentralLayoutWidget)
self.openPath.setMaximumSize(QtCore.QSize(100, 16777215))
self.openPath.setObjectName("openFile_2")
self.centralLayoutWidget.addWidget(self.openPath, 0, QtCore.Qt.AlignHCenter)
self.horizontalLayout.addWidget(self.CentralLayoutWidget)
self.closeButton.clicked.connect(self.close)
QtCore.QMetaObject.connectSlotsByName(self)
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("FileProgress", "Dialog"))
self.filename_label.setText(_translate("FileProgress", "{filename}"))
self.progressLabel.setToolTip(_translate("FileProgress", "<html><head/><body><p>当前进度</p></body></html>"))
self.progressLabel.setText(_translate("FileProgress", f") / {self._cSpeed.get_total()}"))
self.speedLabel.setToolTip(_translate("FileProgress", "<html><head/><body><p>速度</p></body></html>"))
self.speedLabel.setWhatsThis(_translate("FileProgress", "<html><head/><body><p><br/></p></body></html>"))
self.speedLabel.setText(_translate("FileProgress", "speed"))
self.eta.setToolTip(_translate("FileProgress",
"<html><head/><body><p><span style=\" font-weight:600; "
"color:#ff0000;\">eta</span><span style=\" color:#000000;\">, 即</span><span "
"style=\" font-weight:600; color:#000000;\">E</span><span style=\" "
"color:#000000;\">stimated </span><span style=\" font-weight:600; "
"color:#000000;\">T</span><span style=\" color:#000000;\">ime of </span><span "
"style=\" font-weight:600; color:#000000;\">A</span><span style=\" "
"color:#000000;\">rrival, </span><span style=\" font-weight:600; "
"color:#000000;\">预计到达时间</span><span style=\" "
"color:#000000;\">.</span></p></body></html>"))
self.eta.setWhatsThis(_translate("FileProgress", "<html><head/><body><p><br/></p></body></html>"))
self.eta.setText(_translate("FileProgress", "eta"))
self.percentLabel.setText(_translate("FileProgress", "0%"))
self.openFile.setText(_translate("FileProgress", "打开文件"))
self.openPath.setText(_translate("FileProgress", "转到目录"))
self.size_label_tag.setText(_translate("FileProgress", "大小:"))
self.size_label.setText(_translate("FileProgress", self._cSpeed.get_total()))
self.progressbar.setRange(0, 0)
self.setWindowOpacity(0.9)
self.progressbar.setStyleSheet("\n"
"#progressbar {\n"
" min-height: 12px;\n"
" max-height: 12px;\n"
" border-radius: 6px;\n"
"}\n"
"#progressbar::chunk {\n"
" border-radius: 6px;\n"
"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, "
f"stop:0 rgba(50, 0, 255, 255), stop:1 rgba({self._cSpeed.get_percent()}, 185, "
f"255, 255));\n "
"}")
self.openFile.setEnabled(False)
self._cSpeed.add_slot(self.updateValue)
def _set_eta(self):
"""
def _set_eta(self, _stamp: (int, float)):
if self.is_finished():
if not isinstance(self._endTime, (int, float)):
self._endTime = time.time()
self.eta.setText("total " + str(time.strftime("%H:%M:%S",
time.gmtime(float(self._endTime - self._startTime)))))
else:
if _stamp == 0:
self.eta.setText("eta --:--:--")
else:
self.eta.setText("eta " + str(time.strftime("%H:%M:%S", time.gmtime(float(_stamp)))))
"""
self.eta.setText(self._cSpeed.get_eta())
def _set_speed(self):
"""
def _set_speed(self, _transfer: int):
self.speedLabel.setText(f"{'total ' if self.is_finished() else str()}{convert(_transfer)}/s")
"""
self.speedLabel.setText(self._cSpeed.get_speed())
def _set_progress(self):
"""
def _set_progress(self):
if self.is_finished():
self.progressLabel.setText("finished")
else:
self.progressLabel.setText(f"{convert(self.progress)} / {convert(self.total)}")
"""
self.progressLabel.setText(self._cSpeed.get_progress())
def mouseMoveEvent(self, e): # re-write mouseMoveEvent
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
self._startPos = QtCore.QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
@QtCore.pyqtSlot()
def updateValue(self):
self.percent = self._cSpeed.get_percent()
if self._cSpeed.is_finished():
self.openFile.setEnabled(True)
self.progressbar.hide()
self.percentLabel.hide()
if self._cSpeed.get_percent() > 0:
self.progressbar.setMaximum(100)
self.progressbar.setValue(self.percent)
self.percentLabel.setText(f"{self.percent}%")
self._set_speed()
self._set_eta()
self._set_progress()
class ProgressDialog(SimpleProgressDialog):
def __init__(self, _cSpeed, filename, filepath, parent=None):
super(ProgressDialog, self).__init__(parent, cSpeed=_cSpeed)
self.resize(320, 640)
self.filename = filename
self.filepath = filepath
self.file = os.path.join(filepath, filename)
self.icon_label.setPixmap(QtGui.QPixmap(ImageLoader.get(filename)))
self.filename_label.setText(filename)
self.openFile.clicked.connect(self.startFile)
self.openPath.clicked.connect(self.startPath)
self.updateValue()
self.startTimer(500)
self.exec_()
def startFile(self, *args):
if os.path.isfile(self.file):
os.startfile(self.file)
def timerEvent(self, a0: QtCore.QTimerEvent) -> None:
self.updateValue()
def startPath(self, *args):
if os.path.isfile(self.filepath):
os.startfile(self.filepath)
class FileListWidget(QtWidgets.QListWidget):
class ListWidgetLayout(QtWidgets.QWidget):
def __init__(self, name, cSpeed: _cSpeed = _cSpeed(100), parent=None):
super(FileListWidget.ListWidgetLayout, self).__init__(parent)
self._cSpeed = cSpeed
hbox = QtWidgets.QHBoxLayout(self)
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(QtWidgets.QLabel(name + f"\n({self._cSpeed.get_total()})", self))
progress = QtWidgets.QProgressBar()
progress.setMaximum(100)
progress.setStyleSheet("QProgressBar{\n"
"text-align: center;\n"
'font: 9pt "Consolas";\n'
"}")
vbox.setObjectName("name, speed Info")
hbox.setObjectName("Info and Progress")
progress.setTextVisible(True)
progress.setRange(0, 0)
self.eta_label = QtWidgets.QLabel(self)
self.eta_label.setStyleSheet("color: rgb(60, 112, 255);")
vbox.addWidget(self.eta_label)
self.progressbar = progress
vbox.setSpacing(2)
hbox.addLayout(vbox)
hbox.addWidget(progress)
self.setLayout(hbox)
fonts = QtGui.QFont()
fonts.setFamily("Consolas")
fonts.setPointSize(9)
self.setFont(fonts)
self.eta_label.setFont(fonts)
self.start_time = time.time()
self._cSpeed.add_slot(self.updateValue)
self.startTimer(100)
def timerEvent(self, a0: QtCore.QTimerEvent) -> None:
self.eta_label.setText(f"{self._cSpeed.get_speed()} ({self._cSpeed.get_eta()})")
@QtCore.pyqtSlot()
def updateValue(self) -> None:
if self._cSpeed.get_percent() > 0:
self.progressbar.setMaximum(100)
self.progressbar.setValue(self._cSpeed.get_percent())
class ListItem(QtWidgets.QListWidgetItem):
def __init__(self, parent: QtWidgets.QListWidget, icon: QtGui.QIcon, index: int, layout, size=(200, 100)):
super(FileListWidget.ListItem, self).__init__(icon, str(), parent)
self.index_name = index
self.setSizeHint(QtCore.QSize(*size))
self.setSizeHint(QtCore.QSize(*size))
parent.addItem(self)
parent.setItemWidget(self, layout)
DOWNLOAD = 0
UPLOAD = 1
def __init__(self, _save_path, parent=None):
self.x, self.y = 0, 0
self.dialog_index = 0
self.dialog = None
self.rightClickedItem = None
self.path = None
self.fpath = None
self.current = ""
super().__init__(parent)
self.setWindowIcon(QtGui.QIcon("images/file.png"))
self.download = QtGui.QIcon("images/download.png")
self.upload = QtGui.QIcon("images/upload.png")
self.LOAD_dict = {self.DOWNLOAD: self.download,
self.UPLOAD: self.upload}
self.save_path = _save_path
self.pathdict = {}
self.infodict = {}
self.setObjectName("FileDisplayWindow")
self.resize(666, 421)
font = QtGui.QFont()
font.setFamily("Consolas")
self.setFont(font)
self.setWindowTitle(QtCore.QCoreApplication.translate("Dialog", "Files"))
self.itemClicked.connect(self.fileClicked)
self.menu = QtWidgets.QMenu(self)
open_file = QtWidgets.QAction(QtGui.QIcon("images/file.png"), '打开文件', self)
open_file.triggered.connect(self.startfile)
self.menu.addAction(open_file)
open_path = QtWidgets.QAction(QtGui.QIcon("images/folder.png"), '打开文件夹', self)
open_path.triggered.connect(self.startpath)
self.menu.addAction(open_path)
QtCore.QMetaObject.connectSlotsByName(self)
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
super().mousePressEvent(event)
if event.button() == QtCore.Qt.RightButton and self.itemAt(event.pos()):
item = self.itemAt(event.pos())
index: int = item.index_name
self.fpath = self.pathdict[index]
self.path = os.path.dirname(self.fpath)
self.menu.exec(event.globalPos())
@QtCore.pyqtSlot(str, int, int, tuple)
def new_file(self, name, total, size, info):
self.activateWindow() # 窗口置顶
index = len(self.infodict)
_type, local_file = info
_c = _cSpeed(total)
layout = FileListWidget.ListWidgetLayout(name, _c)
self.pathdict[index] = local_file
self.infodict[index] = (_c, name, os.path.dirname(local_file))
item = FileListWidget.ListItem(self, self.LOAD_dict.get(_type, self.UPLOAD), index, layout)
self.show()
@QtCore.pyqtSlot(int)
def update_file(self, index: int):
_c: _cSpeed = self.infodict[index][0]
_c.update_value(1)
def fileClicked(self, item: ListItem):
index = item.index_name
self.dialog = ProgressDialog(*self.infodict[index])
self.dialog_index = index
def startfile(self, *args):
if isinstance(self.fpath, str) and os.path.isfile(self.fpath):
os.startfile(self.fpath)
def startpath(self, *args):
if isinstance(self.path, str) and os.path.isdir(self.path):
os.startfile(self.path)
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
super(FileListWidget, self).mouseMoveEvent(event)
self.x, self.y = event.x(), event.y()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
a = FileListWidget(os.path.join(os.path.dirname(os.path.realpath(__file__)), "database", "resource"))
a.new_file("asdf", 1010, 11111, (0, "C:/users/zhnwe/desktop/1.rte"))
a.executeDelayedItemsLayout() # 或者 show()
for x in range(100):
a.update_file(0)
app.exec_()
图片文件位于ServerProject
项目内的 user > images > filetype 下
地址位于 https://gitcode.net/m0_60394896/python
import os
path = "images/filetype"
unknown = os.path.join(path, "unknown.png").replace("\\", "/")
filedict = {}
def join(filename):
return os.path.join(path, filename).replace("\\", "/")
def get_suffix_img(suf):
return filedict.get(suf, unknown)
def get_suf(filename):
_, suf = os.path.splitext(filename)
return suf.lstrip(".").lower()
def get(filename):
return get_suffix_img(get_suf(filename))
for file in os.listdir(path):
filepath = join(file)
filetype, _ = os.path.splitext(file)
filedict[filetype.lower()] = filepath
base = 1024
def _conv(value: (float, int)) -> str:
value = float(value)
if value.is_integer():
return str(int(value))
else:
return str(round(value, 1))
def convert(byte, fine=False):
"""
位 bit (比特)(Binary Digits):存放一位二进制数,即 0 或 1,最小的存储单位。
字节 byte:8个二进制位为一个字节(B),最常用的单位。
其中1024=2^10 ( 2 的10次方),
1KB (Kilo byte 千字节)=1024B,
1MB (Mega byte 兆字节 简称“兆”)=1024KB,
1GB (Giga byte 吉字节 又称“千兆”)=1024MB,
1TB (Trillion byte 万亿字节 太字节)=1024GB,
1PB(Peta byte 千万亿字节 拍字节)=1024TB,
1EB(Exa byte 百亿亿字节 艾字节)=1024PB"""
if not isinstance(byte, (int, float)):
byte = len(byte)
DEI = f"{byte} bytes"
units = ["b",
"Kb",
"Mb",
"Gb",
"Tb",
"Pb",
"Eb"]
index = 0
while True:
if byte < 1024 or index + 1 >= len(units):
break
byte /= base
index += 1
if fine:
return f"{_conv(byte)}{units[index]}({DEI})"
else:
return f"{_conv(byte)}{units[index]}"
def to_logging(logger):
def log(command):
def _exec_func(*args, **kwargs):
try:
_result = command(*args, **kwargs)
if _result is None:
return True
return _result
except:
logger.exception(str())
return _exec_func
return log