Skip to content

Commit eec3d1f

Browse files
committed
v3 update
1 parent 8b94c13 commit eec3d1f

21 files changed

+1234
-1090
lines changed

.github/workflows/pyinstaller.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ jobs:
1616
- name: Checkout source code
1717
uses: actions/checkout@v4
1818

19-
- name: Set up Python 3.11
19+
- name: Set up Python 3.12
2020
uses: actions/setup-python@v5
2121
with:
22-
python-version: '3.11'
22+
python-version: '3.12'
2323

2424
- name: Install dependencies
2525
run: |
2626
python -m pip install --upgrade pip
27-
pip install pyinstaller "PySide6-Essentials==6.4.0.1"
27+
pip install pyinstaller "PySide6-Essentials==6.6.3.1" "aiohttp==3.12.15"
2828
2929
- name: Install UPX
3030
uses: crazy-max/ghaction-upx@v3
@@ -49,15 +49,15 @@ jobs:
4949
- name: Checkout source code
5050
uses: actions/checkout@v4
5151

52-
- name: Set up Python 3.11
52+
- name: Set up Python 3.12
5353
uses: actions/setup-python@v5
5454
with:
55-
python-version: '3.11'
55+
python-version: '3.12'
5656

5757
- name: Install dependencies
5858
run: |
5959
python -m pip install --upgrade pip
60-
pip install pyinstaller "PySide6-Essentials==6.4.0.1"
60+
pip install pyinstaller "PySide6-Essentials==6.6.3.1" "aiohttp==3.12.15"
6161
6262
- name: Package application
6363
run: |

MainWindow.ui

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,11 @@
161161
<addaction name="optionsMenu"/>
162162
<addaction name="helpMenu"/>
163163
</widget>
164-
<widget class="QStatusBar" name="statusbar"/>
164+
<widget class="QStatusBar" name="statusbar">
165+
<property name="sizeGripEnabled">
166+
<bool>false</bool>
167+
</property>
168+
</widget>
165169
<action name="actSettings">
166170
<property name="text">
167171
<string>设置…</string>

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ Windows 11 系统演示如下:
8484

8585
## 从源代码运行
8686

87-
从源代码运行的方法适用于所有支持图形界面的操作系统,只需 Python >= 3.6(额外安装 `PySide6`)。
87+
从源代码运行的方法适用于所有支持图形界面的操作系统,只需 Python >= 3.8(推荐 3.12 及以上版本)。
8888

8989
对于 Linux 系统:
9090

9191
```bash
9292
$ git clone https://github.com/GoodCoder666/GoogleTranslate_IPFinder.git
9393
$ cd GoogleTranslate_IPFinder
94-
$ pip3 install PySide6
94+
$ pip3 install PySide6 aiohttp
9595
$ python3 main.py
9696
```
9797

dlgAbout.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
<item row="3" column="0">
7474
<widget class="QLabel" name="labCopyright">
7575
<property name="text">
76-
<string>Copyright © GoodCoder666 2025</string>
76+
<string>Copyright © GoodCoder666 2026</string>
7777
</property>
7878
</widget>
7979
</item>

dlgDebug.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ def _insertHtml(self, html):
4343
def _success(self, response_time):
4444
self._insertHtml(f'<font color="green"><b>成功 [{self.currentIP}]:响应时间 {time_repr(response_time)}</b></font><br/>')
4545

46-
def _fail(self, reason):
47-
self._insertHtml(f'<font color="red"><b>失败 [{self.currentIP}]:{escape(reason)}</b></font><br/>')
46+
def _fail(self, error_type, message):
47+
self._insertHtml(f'<font color="red"><b>失败 [{self.currentIP}]:({error_type}) {escape(message)}</b></font><br/>')

dlgScan.ui

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
<item>
5757
<widget class="QLabel" name="labThreads">
5858
<property name="text">
59-
<string>最大线程数:</string>
59+
<string>最大并发数:</string>
6060
</property>
6161
</widget>
6262
</item>
@@ -113,7 +113,22 @@
113113
</item>
114114
<item>
115115
<property name="text">
116-
<string>200</string>
116+
<string>256</string>
117+
</property>
118+
</item>
119+
<item>
120+
<property name="text">
121+
<string>512</string>
122+
</property>
123+
</item>
124+
<item>
125+
<property name="text">
126+
<string>768</string>
127+
</property>
128+
</item>
129+
<item>
130+
<property name="text">
131+
<string>1024</string>
117132
</property>
118133
</item>
119134
</widget>

dlgSettings.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@
198198
</sizepolicy>
199199
</property>
200200
<property name="text">
201-
<string>线程数</string>
201+
<string>并发数</string>
202202
</property>
203203
</widget>
204204
</item>

main.py

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,33 @@ def __lt__(self, other):
2929
return self.secs < other.secs
3030

3131

32+
class ElidedLabel(QLabel):
33+
def __init__(self, parent=None, mode=Qt.ElideRight):
34+
super().__init__(parent)
35+
self._mode = mode
36+
self._full_text = ''
37+
self.setWordWrap(False)
38+
self.setTextInteractionFlags(Qt.NoTextInteraction)
39+
self.setMinimumWidth(0)
40+
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
41+
42+
def setText(self, text: str):
43+
self._full_text = text
44+
self._update_elide()
45+
46+
def resizeEvent(self, event):
47+
super().resizeEvent(event)
48+
self._update_elide()
49+
50+
def _update_elide(self):
51+
w = self.width()
52+
if w > 0:
53+
fm = self.fontMetrics()
54+
super().setText(fm.elidedText(self._full_text, self._mode, w))
55+
else:
56+
super().setText(self._full_text)
57+
58+
3259
class MainWindow(QMainWindow):
3360
SUPPORTED_INPUT_FILTERS = QMainWindow.tr('文本文件(*.txt);;所有文件(*.*)')
3461
SUPPORTED_OUTPUT_FILTERS = QMainWindow.tr('文本文件(*.txt);;CSV 表格(*.csv);;所有文件(*.*)')
@@ -68,6 +95,10 @@ def __init__(self, parent=None):
6895
# clipboard
6996
self.clipboard = QApplication.clipboard()
7097

98+
# status bar
99+
self.ui.statusbar.setContentsMargins(9, 0, 9, 0)
100+
self.ui.statusbar.setStyleSheet('QStatusBar::item { border: none; }')
101+
71102
# settings
72103
self.ui.actResetSettings.triggered.connect(self._reset_settings)
73104
self.settings = QSettings('GoodCoder666', 'IPFinder')
@@ -280,15 +311,15 @@ def _set_buttons_enabled(self, enabled):
280311
self.ui.btnWait_Test.setEnabled(enabled)
281312

282313
def _init_progessBar(self, prog_max):
283-
self.progressBar = QProgressBar(self)
284-
self.progressBar.setFixedWidth(390)
314+
self.progressBar = QProgressBar(self.ui.statusbar)
285315
self.progressBar.setRange(0, prog_max)
286316
self.progressBar.setValue(0)
287-
self.logLabel = QLabel(self)
288-
self.logLabel.setMaximumWidth(370)
317+
self.progressBar.setMaximumHeight(18)
318+
self.logLabel = ElidedLabel(self.ui.statusbar)
319+
self.logLabel.setAlignment(Qt.AlignCenter)
289320
self.ui.statusbar.clearMessage()
290-
self.ui.statusbar.addWidget(self.progressBar)
291-
self.ui.statusbar.addWidget(self.logLabel)
321+
self.ui.statusbar.addWidget(self.progressBar, 1)
322+
self.ui.statusbar.addWidget(self.logLabel, 1)
292323

293324
def _update_progressBar(self, dt=1):
294325
self.progressBar.setValue(self.progressBar.value() + dt)
@@ -301,21 +332,21 @@ def _remove_progessBar(self):
301332
self.progressBar.deleteLater()
302333
self.logLabel.deleteLater()
303334

304-
def _add_result(self, ip, seconds):
335+
def _add_result(self, ip, latency):
305336
self.ui.resultTable.setSortingEnabled(False) # TODO: maybe there's a better way to temporarily disable sorting?
306337

307338
row = self.ui.resultTable.rowCount()
308339
self.ui.resultTable.setRowCount(row + 1)
309340
self.ui.resultTable.setItem(row, 0, QTableWidgetItem(ip))
310-
time_str = time_repr(seconds)
311-
self.ui.resultTable.setItem(row, 1, QTableWidgetTimeItem(seconds, time_str))
341+
time_str = time_repr(latency)
342+
self.ui.resultTable.setItem(row, 1, QTableWidgetTimeItem(latency, time_str))
312343
self.logLabel.setText(self.tr('发现可用IP: %s [%s]') % (ip, time_str))
313344
self._update_progressBar()
314345

315346
self.ui.resultTable.setSortingEnabled(True)
316347

317348
def _found_unavailable(self, ip, reason):
318-
self.logLabel.setText(self.tr('IP %s 不可用 [原因: %s]') % (ip, reason))
349+
self.logLabel.setText(self.tr('IP %s 不可用 [%s]') % (ip, reason))
319350
self._update_progressBar()
320351

321352
def _speedtest_finished(self):
@@ -327,20 +358,21 @@ def _test_ips(self, after_scan=True):
327358
self.ui.resultTable.setRowCount(0)
328359
ips = [self.ui.ipList.item(i).text() for i in range(self.ui.ipList.count())]
329360
if after_scan:
330-
self.progressBar.setValue(0)
331361
self.progressBar.setMaximum(len(ips))
362+
self.progressBar.setValue(0)
363+
self.logLabel.setText(self.tr('扫描完成,开始测速...'))
332364
self.ui.btnWait_Scan.setText(self.tr('扫描'))
333365
self.ui.btnWait_Scan.setEnabled(False)
334366
else:
335367
self._init_progessBar(len(ips))
336368
thread = SpeedtestThread(self, ips,
337369
host=self.settings.value('test/host'),
338370
request_format=self.settings.value('test/template'),
339-
available_callback=self._add_result,
340-
unavailable_callback=self._found_unavailable,
341371
timeout=self.settings.value('test/timeout', type=float),
342372
repeat=self.settings.value('test/repeat', type=int),
343373
num_workers=self.settings.value('test/num_threads', type=int))
374+
thread.foundAvailable.connect(self._add_result)
375+
thread.foundUnavailable.connect(self._found_unavailable)
344376
thread.finished.connect(self._speedtest_finished)
345377
thread.start()
346378

@@ -349,9 +381,9 @@ def on_btnWait_Test_clicked(self):
349381
self._set_buttons_enabled(False)
350382
self._test_ips(False)
351383

352-
def _report_single_scan_result(self, ip):
384+
def _report_single_scan_result(self, ip, latency):
353385
self.ui.ipList.addItem(QListWidgetItem(ip))
354-
self.logLabel.setText(self.tr('发现可用IP: %s') % ip)
386+
self.logLabel.setText(self.tr('发现可用IP: %s [%s]') % (ip, time_repr(latency)))
355387

356388
def _after_scan(self):
357389
self._set_buttons_enabled(True)
@@ -368,6 +400,9 @@ def on_btnWait_Scan_clicked(self):
368400

369401
dlg = dlgScan(self, self.settings.value('scan/ranges'))
370402
if dlg.exec() == QDialog.Accepted:
403+
# TODO: add separate host/template settings for scan?
404+
host = self.settings.value('test/host')
405+
request_format = self.settings.value('test/template')
371406
max_ips = dlg.ui.spinBox_MaxIP.value()
372407
num_workers = int(dlg.ui.comboBox_threads.currentText())
373408
timeout = dlg.ui.spinBox_timeout.value()
@@ -394,13 +429,13 @@ def on_btnWait_Scan_clicked(self):
394429
self._set_buttons_enabled(False)
395430
self.ui.ipList.clear()
396431

397-
thread = ScanThread(self, ip_networks, max_ips, num_workers, timeout, randomized)
432+
thread = ScanThread(self, ip_networks, host, request_format,
433+
max_ips, num_workers, timeout, randomized)
398434
thread.finished.connect(self._test_ips if autoTest else self._after_scan)
399435
thread.foundAvailable.connect(self._report_single_scan_result)
400436
thread.progressUpdate.connect(self._scan_update)
401-
total_addrs = sum(map(len, thread.networks))
402-
self._init_progessBar(total_addrs)
403-
self.logLabel.setText(self.tr('开始扫描,共 %n 个 IP...', '', total_addrs))
437+
self._init_progessBar(thread.total_ips)
438+
self.logLabel.setText(self.tr('开始扫描,共 %n 个 IP...', '', thread.total_ips))
404439
thread.start()
405440

406441
self.sthread = thread

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
PySide6-Essentials
1+
PySide6-Essentials>=6.6.0,<7.0
2+
aiohttp>=3.8.1,<4.0

0 commit comments

Comments
 (0)