Skip to content

Commit 4c89ca2

Browse files
committed
增加换源逻辑,增加ui界面源网络状态检测逻辑,增加部分动画。调用示例参照 文件内 __main__
1 parent 0a3155f commit 4c89ca2

2 files changed

Lines changed: 149 additions & 48 deletions

File tree

media/unfold.png

2.39 KB
Loading

src/CheckUpdateGui.py

Lines changed: 149 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,118 @@
1-
from PyQt5.QtWidgets import QWidget, QScrollArea, QLabel, QVBoxLayout, QApplication, QHBoxLayout, QSpacerItem,\
2-
QSizePolicy, QPushButton,QFrame,QMessageBox,QFormLayout,QProgressDialog,QTextEdit,QComboBox
3-
from githubApi import GitHub, Release,SourceManager,PingThread
4-
from PyQt5.QtCore import QObject,pyqtSlot,Qt,pyqtSignal,QUrl
5-
from PyQt5.QtGui import QDesktopServices,QFont
1+
from PyQt5.QtWidgets import QWidget, QScrollArea, QLabel, QVBoxLayout, QApplication, QHBoxLayout, QSpacerItem, \
2+
QSizePolicy, QPushButton, QFrame, QMessageBox, QFormLayout, QProgressDialog, QTextEdit, QComboBox
3+
from githubApi import GitHub, Release, SourceManager, PingThread
4+
from PyQt5.QtCore import QObject, pyqtSlot, Qt, pyqtSignal, QUrl, QPropertyAnimation, \
5+
QRect, QSize, pyqtProperty, QVariantAnimation
6+
from PyQt5.QtGui import QDesktopServices, QFont, QIcon, QPainter, QPixmap, QPaintEvent
67

78

9+
class AnimationButton(QPushButton):
10+
def __init__(self, parent=None):
11+
super().__init__(parent)
12+
self.pixmap: QPixmap = None
13+
self.clicked.connect(self.animationStart)
14+
self.animation = QVariantAnimation(self)
15+
self.animation.valueChanged.connect(self.setRotate)
16+
self.__rotate = 0
17+
18+
def rotate(self):
19+
return self.__rotate
20+
21+
def setRotate(self, rotate):
22+
self.__rotate = rotate
23+
self.update()
24+
# rotate = property(int,rotate, setRotate)
25+
26+
def paintEvent(self, event):
27+
super().paintEvent(event)
28+
if self.pixmap is not None:
29+
painter = QPainter(self)
30+
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
31+
painter.translate(self.width() / 2, self.height() / 2)
32+
painter.rotate(self.rotate())
33+
painter.drawPixmap(-(self.width()-10) // 2, -(self.height()-10) //
34+
2, self.pixmap.scaled(self.width() - 10, self.height() - 10))
35+
36+
def animationStart(self, check):
37+
if check:
38+
self.animation.setStartValue(0)
39+
self.animation.setEndValue(90)
40+
else:
41+
self.animation.setStartValue(90)
42+
self.animation.setEndValue(0)
43+
self.animation.setDuration(300)
44+
self.animation.start()
45+
846

947
class ReleaseFrame(QFrame):
1048
downLoadFile = pyqtSignal(Release)
11-
def __init__(self, release: Release,mode = ">", parent=None):
49+
50+
def __init__(self, release: Release, mode=">", parent=None):
1251
super().__init__(parent)
1352
self.release: Release = release
14-
self.showButton = QPushButton(QObject.tr(self, "Show"))
53+
self.showButton = AnimationButton()
1554
self.showButton.setCheckable(True)
55+
self.showButton.pixmap = QPixmap("media/unfold.png")
56+
self.titleWidget = QWidget()
1657
self.formWidget = QWidget()
1758
self.downloadButton = QPushButton(QObject.tr(self, "Download"))
18-
self.formWidget.hide()
1959
self.bodyEdit = QTextEdit()
2060
self.mode = mode
2161
self.initUi()
2262
self.initConnect()
63+
self.formWidget.setVisible(False)
2364

2465
def initUi(self):
2566

2667
# self.setFrameShape(QFrame.StyledPanel)
2768
layout = QVBoxLayout()
69+
layout.setContentsMargins(0, 0, 0, 0)
2870
row1 = QHBoxLayout()
2971
row1.addWidget(self.showButton)
3072
row1.addWidget(QLabel(self.release.tag_name))
3173
row1.addItem(QSpacerItem(
3274
20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
3375
self.downloadButton.setEnabled(self.mode == ">")
3476
row1.addWidget(self.downloadButton)
35-
77+
self.titleWidget.setLayout(row1)
78+
self.titleWidget.setContentsMargins(0, 0, 0, 0)
3679
formLayout = QFormLayout()
37-
formLayout.setContentsMargins(0, 0, 0, 0)
3880
urlLabel = QLabel()
39-
urlLabel.setText("<a href='" + self.release.html_url + "'>" + QObject.tr(self,"open external links")+ "</a>")
81+
urlLabel.setText("<a href='" + self.release.html_url +
82+
"'>" + QObject.tr(self, "open external links") + "</a>")
4083
urlLabel.setOpenExternalLinks(True)
4184
dataLayout = QVBoxLayout()
42-
dataLayout.setContentsMargins(0, 0, 0, 0)
4385
formLayout.setLabelAlignment(Qt.AlignmentFlag.AlignLeft)
4486
formLayout.addRow(QObject.tr(self, "html_url"), urlLabel)
45-
formLayout.addRow(QObject.tr(self, "name"), QLabel(self.release.assets_name))
46-
formLayout.addRow(QObject.tr(self, "content_type"), QLabel(self.release.assets_content_type))
47-
formLayout.addRow(QObject.tr(self, "size"), QLabel(str(f"{self.release.assets_size / 1000000:.2f} MB")))
48-
formLayout.addRow(QObject.tr(self, "download_count"), QLabel(str(self.release.assets_download_count)))
49-
formLayout.addRow(QObject.tr(self, "created_at"), QLabel(self.release.assets_created_at))
87+
formLayout.addRow(QObject.tr(self, "name"),
88+
QLabel(self.release.assets_name))
89+
formLayout.addRow(QObject.tr(self, "content_type"),
90+
QLabel(self.release.assets_content_type))
91+
formLayout.addRow(QObject.tr(self, "size"), QLabel(
92+
str(f"{self.release.assets_size / 1000000:.2f} MB")))
93+
formLayout.addRow(QObject.tr(self, "download_count"),
94+
QLabel(str(self.release.assets_download_count)))
95+
formLayout.addRow(QObject.tr(self, "created_at"),
96+
QLabel(self.release.assets_created_at))
5097
downloadUrlLabel = QLabel()
51-
downloadUrlLabel.setText("<a href='" + self.release.assets_browser_download_url + "'>" + QObject.tr(self,"open download links")+ "</a>")
98+
downloadUrlLabel.setText("<a href='" + self.release.assets_browser_download_url +
99+
"'>" + QObject.tr(self, "open download links") + "</a>")
52100
downloadUrlLabel.setOpenExternalLinks(True)
53-
formLayout.addRow(QObject.tr(self, "browser_download_url"), downloadUrlLabel)
101+
formLayout.addRow(QObject.tr(
102+
self, "browser_download_url"), downloadUrlLabel)
54103
dataLayout.addLayout(formLayout)
55104
self.bodyEdit.setMarkdown(self.release.body)
56105
self.bodyEdit.setReadOnly(True)
57106
font = QFont("Microsoft YaHei UI", 13)
58107
font.setBold(True)
59108
self.bodyEdit.setFont(font)
60-
self.bodyEdit.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
109+
self.bodyEdit.setVerticalScrollBarPolicy(
110+
Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
61111
dataLayout.addWidget(self.bodyEdit)
62112
self.formWidget.setLayout(dataLayout)
63113

64-
layout.addLayout(row1)
65-
layout.addWidget(self.formWidget)
114+
layout.addWidget(self.titleWidget)
115+
layout.addWidget(self.formWidget)
66116
self.setLayout(layout)
67117
rgbStr = ""
68118
if self.mode == ">":
@@ -75,22 +125,47 @@ def initUi(self):
75125
# 样式表红色背景
76126
rgbStr = "rgb(249, 179, 163)"
77127
# label字体微软雅黑Ui,大小13
78-
self.setStyleSheet(f"QFrame{{background-color:{rgbStr}; font-family:Microsoft YaHei UI; font-size:14px;}}")
79-
128+
self.setStyleSheet(
129+
f"QFrame{{background-color:{rgbStr}; font-family:Microsoft YaHei UI; font-size:14px;}}")
130+
80131
def initConnect(self):
81132
self.showButton.clicked.connect(self.showButtonClicked)
82133
self.downloadButton.clicked.connect(self.downLoadButtonClicked)
83-
def showButtonClicked(self,checked:bool):
134+
135+
def showButtonClicked(self, checked: bool):
136+
self.formWidget.setVisible(True)
137+
animation = QPropertyAnimation(self.formWidget, b"size", self)
138+
animation2 = QPropertyAnimation(self, b"size", self)
139+
animation.setDuration(300)
140+
animation2.setDuration(300)
141+
start: QSize = None
142+
end: QSize = None
143+
start1: QSize = None
144+
end1: QSize = None
84145
if checked:
85-
self.formWidget.show()
146+
start = QSize(self.width(), 0)
147+
start1 = QSize(self.width(), self.titleWidget.height())
148+
end = QSize(self.width(), self.formWidget.sizeHint().height())
149+
end1 = QSize(self.width(), self.sizeHint().height())
86150
else:
87-
self.formWidget.hide()
151+
start = QSize(self.width(), self.formWidget.sizeHint().height())
152+
start1 = QSize(self.width(), self.sizeHint().height())
153+
end = QSize(self.width(), 0)
154+
end1 = QSize(self.width(), self.titleWidget.height())
155+
animation.setStartValue(start)
156+
animation.setEndValue(end)
157+
animation2.setStartValue(start1)
158+
animation2.setEndValue(end1)
159+
animation2.start(QPropertyAnimation.DeletionPolicy.DeleteWhenStopped)
160+
animation.start(QPropertyAnimation.DeletionPolicy.DeleteWhenStopped)
161+
animation.finished.connect(lambda: self.formWidget.setVisible(checked))
162+
88163
def downLoadButtonClicked(self):
89164
self.downLoadFile.emit(self.release)
90-
165+
91166

92167
class CheckUpdateGui(QWidget):
93-
def __init__(self,github:GitHub, parent=None):
168+
def __init__(self, github: GitHub, parent=None):
94169
super().__init__(parent)
95170
self.github: GitHub = github
96171
self.github.setParent(self)
@@ -102,26 +177,36 @@ def __init__(self,github:GitHub, parent=None):
102177
self.releaseArea.setHorizontalScrollBarPolicy(
103178
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
104179
)
180+
self.pingThread = None
181+
self.sourceSpeedLabel = QLabel()
105182
self.sourceCombo = QComboBox()
106183
self.sourceCombo.addItems(self.github.sourceManager.sources.keys())
107-
self.sourceCombo.setCurrentText(self.github.sourceManager.currentSource)
108-
self.currentVersionLabel = QLabel(f"Current Version:{self.github.version}")
184+
self.sourceCombo.setCurrentText(
185+
self.github.sourceManager.currentSource)
186+
self.currentVersionLabel = QLabel(
187+
f"Current Version:{self.github.version}")
109188
self.processDialog = None
110189
self.initUi()
111190
self.initConnect()
112191
self.resize(450, 600)
113192
self.checkUpdateButton.click()
193+
self.changeSource(self.github.sourceManager.currentSource)
194+
114195
def initUi(self):
115196
font = QFont("Microsoft YaHei UI", 13)
116197
font.setBold(True)
117198
self.currentVersionLabel.setFont(font)
199+
font.setBold(False)
200+
font.setPointSize(12)
201+
self.sourceSpeedLabel.setFont(font)
118202
layout = QVBoxLayout()
119203

120204
row1 = QHBoxLayout()
121205
row1.setContentsMargins(0, 0, 0, 0)
122206
row1.addWidget(self.currentVersionLabel)
123207
row1.addItem(QSpacerItem(
124208
20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
209+
row1.addWidget(self.sourceSpeedLabel)
125210
row1.addWidget(self.sourceCombo)
126211
row1.addWidget(self.checkUpdateButton)
127212

@@ -130,67 +215,83 @@ def initUi(self):
130215

131216
row2.addWidget(self.releaseArea)
132217

133-
134218
layout.addLayout(row1)
135219
layout.addLayout(row2)
136220

137221
self.setLayout(layout)
138222

139223
def initConnect(self):
140-
self.checkUpdateButton.clicked.connect(lambda: self.github.releases())
224+
self.checkUpdateButton.clicked.connect(lambda: self.github.releases())
141225
self.github.releasesAsyncSignal.connect(self.checkUpdate)
142226
self.github.errorSignal.connect(self.showError)
143-
self.github.downloadReleaseAsyncStartSignal.connect(self.showDownloadDialog)
144-
self.github.downloadReleaseAsyncProgressSignal.connect(self.updateDownloadDialog)
145-
self.github.downloadReleaseAsyncFinishSignal.connect(self.hideDownloadDialog)
146-
227+
self.github.downloadReleaseAsyncStartSignal.connect(
228+
self.showDownloadDialog)
229+
self.github.downloadReleaseAsyncProgressSignal.connect(
230+
self.updateDownloadDialog)
231+
self.github.downloadReleaseAsyncFinishSignal.connect(
232+
self.hideDownloadDialog)
233+
self.sourceCombo.currentTextChanged.connect(self.changeSource)
234+
def changeSource(self, source: str):
235+
self.pingThread = PingThread(source, self.github.sourceManager.sources[source])
236+
self.sourceSpeedLabel.setText("---ms")
237+
self.pingThread.pingSignal.connect(lambda x,y: self.sourceSpeedLabel.setText(f"{int(y)}ms"))
238+
self.pingThread.start()
147239
@pyqtSlot(list)
148-
def checkUpdate(self,releases:list):
240+
def checkUpdate(self, releases: list):
149241
widget = self.releaseArea.widget()
150242
if widget is not None:
151243
widget.deleteLater()
152244
widget = QWidget()
153245
layout = QVBoxLayout()
154246
layout.setContentsMargins(0, 0, 0, 0)
155247
for release in releases:
156-
frame = ReleaseFrame(release,self.github.compareVersion(release.tag_name))
248+
frame = ReleaseFrame(
249+
release, self.github.compareVersion(release.tag_name))
157250
layout.addWidget(frame)
158251
frame.downLoadFile.connect(self.github.downloadRelease)
159252
# 底部加一个空白区域
160253
panel = QWidget()
161254
panel.setContentsMargins(0, 0, 0, 0)
162255
panel.setFixedHeight(100)
163256
layout.addWidget(panel)
164-
layout.addItem(QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding))
257+
layout.addItem(QSpacerItem(
258+
20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding))
165259
widget.setLayout(layout)
166260
self.releaseArea.setWidget(widget)
167-
def showError(self,msg:str):
168-
QMessageBox.critical(self,QObject.tr(self, "Error"),msg)
169261

170-
def showDownloadDialog(self,release:Release):
262+
def showError(self, msg: str):
263+
QMessageBox.critical(self, QObject.tr(self, "Error"), msg)
264+
265+
def showDownloadDialog(self, release: Release):
171266
if self.processDialog is not None:
172267
self.processDialog.close()
173268
self.processDialog = QProgressDialog(self)
174-
self.processDialog.setWindowTitle(QObject.tr(self, f"{release.tag_name} Downloading..."))
175-
def updateDownloadDialog(self,a:int,b:int):
269+
self.processDialog.setWindowTitle(QObject.tr(
270+
self, f"{release.tag_name} Downloading..."))
271+
272+
def updateDownloadDialog(self, a: int, b: int):
176273
if self.processDialog is not None:
177274
self.processDialog.setValue(a)
178275
self.processDialog.setMaximum(b)
179-
self.processDialog.setLabelText(f'{a/1000000 : .2f}/{b/1000000 : .2f} MB')
180-
def hideDownloadDialog(self,path:str):
276+
self.processDialog.setLabelText(
277+
f'{a/1000000 : .2f}/{b/1000000 : .2f} MB')
278+
279+
def hideDownloadDialog(self, path: str):
181280
if self.processDialog is not None:
182281
self.processDialog.close()
183282
self.processDialog = None
184283
# 使用系统默认方式打开文件
185284
QDesktopServices.openUrl(QUrl.fromLocalFile(path))
186285

286+
187287
if __name__ == '__main__':
188288
import sys
189289
app = QApplication(sys.argv)
190290
data = {
191291
"Github": "https://api.github.com/repos/",
192292
"fff666": "https://fff666.top/",
193293
}
194-
w = CheckUpdateGui(GitHub(SourceManager(data),"eee555", "Solvable-Minesweeper", "3.1.9", "(\d+\.\d+\.\d+)"))
294+
w = CheckUpdateGui(GitHub(SourceManager(data), "eee555",
295+
"Solvable-Minesweeper", "3.1.9", "(\d+\.\d+\.\d+)"))
195296
w.show()
196297
sys.exit(app.exec_())

0 commit comments

Comments
 (0)