PyQt5實(shí)現(xiàn)多界面自由切換的完整項(xiàng)目實(shí)踐指南
簡(jiǎn)介
在Python GUI開發(fā)中,PyQt5提供了強(qiáng)大的界面構(gòu)建能力,支持通過QMainWindow、QStackedWidget和QWizard等組件實(shí)現(xiàn)多界面來回切換。本項(xiàng)目圍繞“多界面切換”這一核心需求,結(jié)合實(shí)際應(yīng)用場(chǎng)景,詳細(xì)演示如何在登錄頁(yè)、主窗口與向?qū)搅鞒讨g進(jìn)行靈活跳轉(zhuǎn)。通過main.py作為程序入口,集成由Qt Designer生成的UI布局文件,并利用事件驅(qū)動(dòng)機(jī)制(如按鈕點(diǎn)擊)觸發(fā)界面切換邏輯,幫助開發(fā)者掌握PyQt5中多窗口管理的核心技術(shù),提升桌面應(yīng)用的交互性與可維護(hù)性。
你有沒有遇到過這樣的情況:項(xiàng)目初期,UI只是簡(jiǎn)單的幾個(gè)按鈕和輸入框,代碼寫得飛快;可幾個(gè)月后,界面越堆越多,跳轉(zhuǎn)邏輯錯(cuò)綜復(fù)雜,每次改一個(gè)小功能都像在拆炸彈?我見過太多團(tuán)隊(duì)被“界面耦合”拖垮——一個(gè)頁(yè)面改了ID,三個(gè)地方報(bào)錯(cuò);切換頁(yè)面卡頓、內(nèi)存蹭蹭上漲……這背后,往往不是技術(shù)不行,而是 架構(gòu)選擇出了問題 。
今天咱們就來聊聊,如何用 PyQt5 構(gòu)建一個(gè)既靈活又穩(wěn)定、能從小工具一路撐到企業(yè)級(jí)應(yīng)用的多界面系統(tǒng)。我們不光講“怎么寫”,更要說清楚“為什么這么寫”。畢竟,真正的高手,拼的是架構(gòu)思維
主窗口不只是個(gè)容器:QMainWindow 的設(shè)計(jì)哲學(xué)
先問一個(gè)問題:你在寫 PyQt 應(yīng)用時(shí),是直接繼承 QWidget 還是 QMainWindow ?別小看這個(gè)選擇,它決定了你的應(yīng)用是“玩具”還是“專業(yè)工具”。
很多初學(xué)者圖省事,上來就 class MyWindow(QWidget) ,結(jié)果做到后面發(fā)現(xiàn):菜單加不上、狀態(tài)欄不會(huì)弄、工具欄位置亂飄……最后只能推倒重來。而 QMainWindow 從出生那天起,就是為“完整桌面應(yīng)用”準(zhǔn)備的。
它到底強(qiáng)在哪
想象一下 Photoshop 或者 VS Code 這類軟件,是不是都有這么一套布局:
- 頂部一排菜單(文件、編輯、視圖…)
- 上面或側(cè)面一堆快捷按鈕(保存、撤銷、運(yùn)行…)
- 底部顯示狀態(tài)信息(縮放比例、光標(biāo)位置…)
- 中間一大塊區(qū)域放核心內(nèi)容
- 左右還能??棵姘澹▓D層、資源管理器…)
這個(gè)結(jié)構(gòu),Qt 叫它 “主窗口模式”(Main Window Pattern) ,而 QMainWindow 就是它的標(biāo)準(zhǔn)實(shí)現(xiàn)。
from PyQt5.QtWidgets import QMainWindow, QLabel
from PyQt5.QtCore import Qt
class ProfessionalApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("專業(yè)級(jí)應(yīng)用示例")
self.resize(1000, 700)
# ? 唯一必須設(shè)置的部分:中央部件
central = QLabel("這里是你的主界面", alignment=Qt.AlignCenter)
self.setCentralWidget(central)
# ?? 下面這些,隨你開不開,全由你控制
self._setup_menu_bar()
self._setup_tool_bars()
self._setup_status_bar()
self._setup_dock_widgets()
看到?jīng)]?中央部件是唯一強(qiáng)制項(xiàng),其他全是可選模塊。這種“中心+邊緣”的設(shè)計(jì),不只是為了好看,更是為了 職責(zé)分離 :
| 區(qū)域 | 職責(zé) | 開發(fā)建議 |
|---|---|---|
| 中央部件 | 承載主業(yè)務(wù)邏輯,用戶注意力焦點(diǎn) | 放 QStackedWidget ,管理多個(gè)頁(yè)面 |
| 菜單欄 | 系統(tǒng)化功能入口,適合層級(jí)命令 | 如“文件 → 導(dǎo)出 → PDF” |
| 工具欄 | 高頻操作快捷通道 | 圖標(biāo)+文字,支持拖動(dòng)???/td> |
| 狀態(tài)欄 | 實(shí)時(shí)反饋與上下文提示 | 顯示進(jìn)度、鼠標(biāo)懸停說明等 |
| ??看翱?/td> | 輔助性浮動(dòng)面板 | 如調(diào)試日志、屬性編輯 |
小知識(shí): QMainWindow 內(nèi)部其實(shí)是個(gè) QMenuBar + QToolBar + QStatusBar + CentralWidget + DockWidgetArea 的組合體,但它把這些細(xì)節(jié)封裝好了,讓你不用手動(dòng)算坐標(biāo)、調(diào)尺寸。
舉個(gè)真實(shí)場(chǎng)景:智能音箱配置工具
假設(shè)你在做一個(gè)藍(lán)牙音箱的 PC 配置工具,用戶需要完成以下流程:
- 登錄賬號(hào)
- 掃描并連接設(shè)備
- 調(diào)整音效參數(shù)
- 固件升級(jí)
- 查看幫助文檔
這時(shí)候你會(huì)怎么做?一個(gè)個(gè)彈窗跳?那體驗(yàn)肯定糟透了。更好的方式是: 主窗口不動(dòng),只換中間的內(nèi)容區(qū) 。
這就引出了我們今天的主角—— QStackedWidget 。
graph TD
A[QMainWindow] --> B[頂部: 菜單欄]
A --> C[左側(cè)/右側(cè): ??棵姘澹蛇x)]
A --> D[底部: 狀態(tài)欄]
A --> E[四周: 工具欄(可浮動(dòng))]
A --> F[中心: QStackedWidget ← 關(guān)鍵!]
F --> G[頁(yè)面0: 登錄頁(yè)]
F --> H[頁(yè)面1: 設(shè)備列表]
F --> I[頁(yè)面2: 音效設(shè)置]
F --> J[頁(yè)面3: 固件更新]
F --> K[頁(yè)面4: 幫助中心]
看到了嗎?所有頁(yè)面都在同一個(gè)主框架下切換,菜單、工具欄保持一致,用戶始終知道自己“在哪”,這就是專業(yè)感的來源 。
QStackedWidget:不只是“翻頁(yè)”,它是界面調(diào)度中樞
說到 QStackedWidget ,很多人以為它就是個(gè)“翻牌器”——點(diǎn)一下,換一頁(yè)。但如果你只把它當(dāng)這么用,那就太浪費(fèi)了。
它的真正價(jià)值在于: 以最小代價(jià)實(shí)現(xiàn)多界面共存與動(dòng)態(tài)調(diào)度 。
它是怎么工作的
簡(jiǎn)單說, QStackedWidget 是一個(gè)“只有一個(gè)孩子”的父親。雖然它肚子里藏了一堆 QWidget ,但每次只讓一個(gè)出來見人,其他的都藏起來( hide() ),但不殺掉( delete )。
from PyQt5.QtWidgets import QStackedWidget, QWidget, QVBoxLayout, QPushButton
class PageController(QStackedWidget):
def __init__(self):
super().__init__()
self._pages = {} # 緩存頁(yè)面實(shí)例
self.init_pages()
def init_pages(self):
# 頁(yè)面0 - 主頁(yè)
home = QWidget()
layout = QVBoxLayout()
layout.addWidget(QPushButton("去設(shè)置"))
home.setLayout(layout)
self.addWidget(home)
self._pages['home'] = home
# 頁(yè)面1 - 設(shè)置頁(yè)
settings = QWidget()
layout = QVBoxLayout()
layout.addWidget(QPushButton("回主頁(yè)"))
settings.setLayout(layout)
self.addWidget(settings)
self._pages['settings'] = settings
# 默認(rèn)顯示首頁(yè)
self.setCurrentIndex(0)
這里有幾個(gè)關(guān)鍵點(diǎn)你必須知道:
- 頁(yè)面不會(huì)被銷毀 :除非你手動(dòng)
removeWidget()+deleteLater(),否則它們一直活在內(nèi)存里。 - 索引決定顯示誰(shuí) :當(dāng)前顯示的是哪個(gè)頁(yè)面,完全由
currentIndex控制。 - 可以監(jiān)聽切換事件 :
currentChanged(int)信號(hào)告訴你“用戶剛?cè)チ四?rdquo;。
# 監(jiān)聽頁(yè)面切換
self.currentChanged.connect(self.on_page_changed)
def on_page_changed(self, index):
print(f"?? 用戶進(jìn)入了第 {index} 個(gè)頁(yè)面")
page_map = {0: "主頁(yè)", 1: "設(shè)置頁(yè)"}
self.parent().statusBar().showMessage(f"進(jìn)入: {page_map.get(index, '未知')}")
# 更進(jìn)一步:根據(jù)頁(yè)面類型執(zhí)行不同邏輯
current_widget = self.widget(index)
if hasattr(current_widget, 'on_enter'):
current_widget.on_enter() # 觸發(fā)頁(yè)面專屬的“進(jìn)入”行為
注意: widget(index) 返回的是原始指針,如果該索引無效會(huì)返回 None ,記得判空!
懶加載:大項(xiàng)目必學(xué)的性能優(yōu)化技巧
但問題來了:如果我有10個(gè)頁(yè)面,全都一次性創(chuàng)建,啟動(dòng)時(shí)會(huì)不會(huì)很慢??jī)?nèi)存會(huì)不會(huì)爆?
當(dāng)然會(huì)!尤其是那些包含圖表、視頻播放器、大量數(shù)據(jù)加載的頁(yè)面。這時(shí)候就得上 懶加載(Lazy Loading) 。
核心思想: 只有當(dāng)用戶第一次訪問某個(gè)頁(yè)面時(shí),才真正創(chuàng)建它 。
class LazyStackedWidget(QStackedWidget):
def __init__(self):
super().__init__()
self._factories = {} # 存儲(chǔ)“造頁(yè)面”的函數(shù)
self._loaded = set() # 記錄已加載的頁(yè)面索引
def add_lazy_page(self, index: int, create_func, placeholder_text="加載中..."):
"""注冊(cè)一個(gè)延遲加載的頁(yè)面"""
placeholder = QLabel(placeholder_text, alignment=Qt.AlignCenter)
self.insertWidget(index, placeholder)
self._factories[index] = create_func
# 當(dāng)該頁(yè)面首次被激活時(shí),才真正創(chuàng)建
def load_once():
if index not in self._loaded:
real_page = create_func()
self.removeWidget(placeholder)
self.insertWidget(index, real_page)
self._loaded.add(index)
placeholder.deleteLater()
# 使用一次性的連接,避免重復(fù)觸發(fā)
from functools import partial
self.widgetRemoved.connect(partial(lambda i, f=load_once: f() if i == index else None))
def setCurrentIndex(self, index):
# 強(qiáng)制刷新:先移除再設(shè)回,觸發(fā) widgetRemoved 信號(hào)
if index in self._factories and index not in self._loaded:
old_idx = self.currentIndex()
self.parent().setCentralWidget(QWidget()) # 臨時(shí)替換
self.parent().setCentralWidget(self) # 再換回來
super().setCurrentIndex(old_idx)
super().setCurrentIndex(index)
else:
super().setCurrentIndex(index)
用法也很簡(jiǎn)單:
def create_heavy_page():
# 模擬耗時(shí)操作
import time; time.sleep(1)
page = QWidget()
page.setLayout(QVBoxLayout())
page.layout().addWidget(QLabel("這是個(gè)重型頁(yè)面,加載花了1秒"))
return page
stack = LazyStackedWidget()
stack.add_lazy_page(0, lambda: QLabel("輕量首頁(yè)"), "首頁(yè)")
stack.add_lazy_page(1, create_heavy_page, "重型頁(yè)面...")
這樣,啟動(dòng)瞬間就能看到首頁(yè),點(diǎn)擊“去重型頁(yè)面”時(shí)才會(huì)卡一下——用戶體驗(yàn)好太多了 。
別再硬編碼索引了!解耦才是高級(jí)玩法
現(xiàn)在我們解決了“頁(yè)面怎么放”的問題,接下來是“怎么切”。
你可能見過這種寫法:
btn.clicked.connect(lambda: stack.setCurrentIndex(1)) # ? 硬編碼!
看著沒問題,但如果哪天你把“設(shè)置頁(yè)”挪到了第3個(gè)位置呢?所有 setCurrentIndex(1) 都得改,簡(jiǎn)直是維護(hù)噩夢(mèng)。
更好的方式:按對(duì)象切換
PyQt 早就想到了這一點(diǎn),提供了 setCurrentWidget(QWidget*) 方法:
settings_page = SettingsWidget() stack.addWidget(settings_page) btn.clicked.connect(lambda: stack.setCurrentWidget(settings_page)) # ? 推薦!
現(xiàn)在不管它在第幾個(gè)位置,都能準(zhǔn)確跳轉(zhuǎn)。而且代碼自解釋性強(qiáng)多了:“我要去設(shè)置頁(yè)”,而不是“我要去第1頁(yè)”。
最優(yōu)雅的方式:信號(hào)驅(qū)動(dòng) + 導(dǎo)航混入
真正的大項(xiàng)目,應(yīng)該做到 頁(yè)面自己不知道外面有個(gè)堆棧 。也就是說,登錄頁(yè)不應(yīng)該直接調(diào)用 stack.setCurrentIndex(1) ,因?yàn)樗静辉撝?ldquo;主頁(yè)面是第1頁(yè)”。
解決方案: 自定義信號(hào) + 導(dǎo)航控制器 。
from PyQt5.QtCore import pyqtSignal
class NavigationRequest(QObject):
goto_login = pyqtSignal()
goto_main = pyqtSignal()
goto_settings = pyqtSignal()
goto_help = pyqtSignal()
# 全局信號(hào)總線(或作為主窗口成員)
nav = NavigationRequest()
class LoginPage(QWidget):
def __init__(self):
super().__init__()
btn = QPushButton("登錄")
btn.clicked.connect(self.try_login)
def try_login(self):
# 模擬驗(yàn)證
if self.validate():
nav.goto_main.emit() # 發(fā)信號(hào):我要去主頁(yè)面!
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.stack = QStackedWidget()
self.setCentralWidget(self.stack)
# 創(chuàng)建頁(yè)面
self.login_page = LoginPage()
self.main_page = MainPage()
self.settings_page = SettingsPage()
self.stack.addWidget(self.login_page)
self.stack.addWidget(self.main_page)
self.stack.addWidget(self.settings_page)
# 統(tǒng)一處理導(dǎo)航信號(hào)
nav.goto_main.connect(lambda: self.stack.setCurrentWidget(self.main_page))
nav.goto_settings.connect(lambda: self.stack.setCurrentWidget(self.settings_page))
nav.goto_help.connect(lambda: self.stack.setCurrentWidget(self.help_page))
你看,登錄頁(yè)只負(fù)責(zé)“發(fā)出請(qǐng)求”,主窗口負(fù)責(zé)“響應(yīng)請(qǐng)求”。兩者完全解耦,隨便你怎么改頁(yè)面順序、增減頁(yè)面,都不影響原有邏輯。
提示:你可以把這個(gè)模式封裝成一個(gè) NavigationMixin ,讓所有頁(yè)面都能輕松調(diào)用 self.goto_main() 。
數(shù)據(jù)怎么傳?別用全局變量!
另一個(gè)高頻問題是:頁(yè)面之間怎么傳數(shù)據(jù)?
比如登錄成功后,怎么把用戶名傳給主頁(yè)面?
新手常犯的錯(cuò)誤是搞個(gè) global current_user ,然后到處引用。短期看挺好使,長(zhǎng)期看埋雷。
正確姿勢(shì):構(gòu)造函數(shù)傳參 or 屬性注入
最干凈的方式是在創(chuàng)建頁(yè)面時(shí)就把數(shù)據(jù)塞進(jìn)去:
class MainPage(QWidget):
def __init__(self, user: User):
super().__init__()
self.user = user
layout = QVBoxLayout()
layout.addWidget(QLabel(f"歡迎回來,{user.username}!"))
self.setLayout(layout)
# 登錄成功后
user = User(username="alice", role="admin")
main_page = MainPage(user)
stack.addWidget(main_page)
nav.goto_main.emit()
或者通過屬性設(shè)置:
main_page.user = user # 在 emit 前設(shè)置 nav.goto_main.emit()
復(fù)雜場(chǎng)景:用事件總線或狀態(tài)管理
如果你的應(yīng)用足夠復(fù)雜(比如十幾頁(yè)、多人協(xié)作),建議引入 事件總線(Event Bus) 或輕量級(jí)狀態(tài)管理。
class AppState(QObject):
user_changed = pyqtSignal(User)
def __init__(self):
super().__init__()
self._current_user = None
@property
def current_user(self):
return self._current_user
@current_user.setter
def current_user(self, value):
self._current_user = value
self.user_changed.emit(value)
# 全局狀態(tài)
app_state = AppState()
# 任何頁(yè)面監(jiān)聽用戶變化
app_state.user_changed.connect(lambda u: print(f"用戶變更為: {u.username}"))
這樣,無論哪個(gè)頁(yè)面修改了用戶狀態(tài),其他頁(yè)面都能自動(dòng)收到通知,徹底告別“手動(dòng)同步”。
Qt Designer + PyUIC:可視化開發(fā)的正確打開方式
說了這么多代碼,是不是覺得 UI 布局太麻煩?別忘了,PyQt5 配套的 Qt Designer 才是生產(chǎn)力神器!
為什么一定要用 .ui 文件
因?yàn)椋?/p>
- 拖拖拽拽就能畫界面,效率提升80%
- 界面和邏輯分離,美工改 UI 不影響代碼
- 支持預(yù)覽不同分辨率下的效果
- 可版本控制
.ui文件(XML格式)
操作步驟很簡(jiǎn)單:
- 打開
designer(命令行輸入即可) - 新建一個(gè)
Widget或Main Window - 拖控件、設(shè)屬性、調(diào)布局
- 保存為
login.ui
然后用 pyuic5 轉(zhuǎn)成 Python 文件:
pyuic5 -x ui/login.ui -o views/ui_login.py
生成的代碼長(zhǎng)這樣:
class Ui_LoginForm(object):
def setupUi(self, LoginForm):
LoginForm.setObjectName("LoginForm")
LoginForm.resize(400, 300)
self.lineEdit_username = QLineEdit(LoginForm)
self.lineEdit_username.setGeometry(...)
self.lineEdit_password = QLineEdit(LoginForm)
self.lineEdit_password.setEchoMode(QLineEdit.Password)
self.btn_login = QPushButton("登錄", LoginForm)
def retranslateUi(self, LoginForm):
_translate = QCoreApplication.translate
LoginForm.setWindowTitle(_translate("LoginForm", "登錄"))
接著你在自己的類里組合它:
from views.ui_login import Ui_LoginForm
class LoginWindow(QWidget, Ui_LoginForm):
def __init__(self):
super().__init__()
self.setupUi(self) # 自動(dòng)生成界面
self.btn_login.clicked.connect(self.handle_login)
def handle_login(self):
username = self.lineEdit_username.text()
password = self.lineEdit_password.text()
if authenticate(username, password):
app_state.current_user = User(username, "user")
nav.goto_main.emit()
else:
QMessageBox.warning(self, "錯(cuò)誤", "用戶名或密碼錯(cuò)誤")
看到?jīng)]?UI 自動(dòng)搭建,你只管寫邏輯。這才是現(xiàn)代化開發(fā)的樣子!
工程化部署:從腳本到獨(dú)立程序
最后一步:打包發(fā)布。
沒人愿意讓用戶裝 Python 才能運(yùn)行你的程序,對(duì)吧?所以我們用 PyInstaller 把整個(gè)項(xiàng)目打成一個(gè) .exe (Windows)或 .app (macOS)。
自動(dòng)化編譯 UI 文件
先寫個(gè)腳本,一鍵把所有 .ui 轉(zhuǎn)成 .py :
# tools/compile_ui.py
import os
import subprocess
UI_DIR = "ui"
VIEWS_DIR = "views"
def compile_all():
for file in os.listdir(UI_DIR):
if file.endswith(".ui"):
input_path = os.path.join(UI_DIR, file)
output_name = f"ui_{file[:-3]}.py"
output_path = os.path.join(VIEWS_DIR, output_name)
cmd = ["pyuic5", "-o", output_path, input_path]
subprocess.run(cmd, check=True)
print(f"? 生成: {output_path}")
if __name__ == "__main__":
compile_all()
以后每次改完 UI,運(yùn)行 python tools/compile_ui.py 就行。
打包成獨(dú)立可執(zhí)行文件
安裝 PyInstaller:
pip install pyinstaller
然后打包:
pyinstaller \
--onefile \
--windowed \
--name "智能音箱配置工具" \
--icon assets/app.ico \
--add-data "ui;ui" \
main.py
參數(shù)說明:
| 參數(shù) | 作用 |
|---|---|
| --onefile | 所有文件打成一個(gè) exe |
| --windowed | 不彈黑框(適合 GUI 應(yīng)用) |
| --icon | 設(shè)置程序圖標(biāo) |
| --add-data | 添加額外資源(如 .ui 文件) |
最終生成 dist/智能音箱配置工具.exe ,雙擊就能運(yùn)行,完全不需要 Python 環(huán)境 。
總結(jié):構(gòu)建可持續(xù)演進(jìn)的 PyQt 應(yīng)用
回顧一下,我們今天聊的不是一個(gè)簡(jiǎn)單的“多頁(yè)面切換”技巧,而是一整套 現(xiàn)代 PyQt 桌面應(yīng)用的架構(gòu)范式 :
- 用
QMainWindow+QStackedWidget搭建主框架 :穩(wěn)定、專業(yè)、易于擴(kuò)展; - 頁(yè)面懶加載 :避免啟動(dòng)卡頓,提升用戶體驗(yàn);
- 信號(hào)驅(qū)動(dòng)導(dǎo)航 :解耦頁(yè)面與控制器,提高可維護(hù)性;
- Qt Designer + PyUIC :實(shí)現(xiàn) UI 與邏輯分離,提升開發(fā)效率;
- 狀態(tài)管理替代全局變量 :讓數(shù)據(jù)流動(dòng)更清晰、更安全;
- PyInstaller 打包發(fā)布 :交付即用型產(chǎn)品,無需依賴環(huán)境。
這套組合拳下來,哪怕你的項(xiàng)目從一個(gè)小工具慢慢長(zhǎng)成一個(gè)復(fù)雜系統(tǒng),也能穩(wěn)如老狗。
記住一句話: 好的架構(gòu)不是一開始設(shè)計(jì)出來的,而是在一次次迭代中堅(jiān)持原則演化出來的 。別怕麻煩,先把架子搭正,后面的路才會(huì)越走越寬。
以上就是PyQt5實(shí)現(xiàn)多界面自由切換的完整項(xiàng)目實(shí)踐指南的詳細(xì)內(nèi)容,更多關(guān)于PyQt5界面切換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python 使用tkinter+you-get實(shí)現(xiàn)視頻下載器
這篇文章主要介紹了python 使用tkinter+you-get實(shí)現(xiàn)視頻下載器,幫助大家方便的下載視頻資源,感興趣的朋友可以了解下2020-11-11
Python推導(dǎo)式Comprehensions的終極入門指南
在 Python 的世界里,你經(jīng)常會(huì)聽到Pythonic,而推導(dǎo)式正是 Pythonic 代碼的典型代表,本文將帶你從零開始,系統(tǒng)地掌握 Python 中的列表、字典、集合推導(dǎo)式以及生成器表達(dá)式,希望對(duì)大家有所幫助2025-12-12
Python自動(dòng)化操控鼠標(biāo)的零基礎(chǔ)完全指南
在日常的電腦使用中,我們經(jīng)常會(huì)遇到大量重復(fù)性的鼠標(biāo)操作,通過使用?Python?腳本,你可以讓電腦自動(dòng)、精準(zhǔn)地移動(dòng)鼠標(biāo)、執(zhí)行點(diǎn)擊甚至滾動(dòng)頁(yè)面,本篇指南將帶你從零開始,系統(tǒng)地學(xué)習(xí)如何使用?Python?操控你的鼠標(biāo),開啟桌面自動(dòng)化的第一步2026-04-04
Python基于keras訓(xùn)練實(shí)現(xiàn)微笑識(shí)別的示例詳解
Keras是一個(gè)由Python編寫的開源人工神經(jīng)網(wǎng)絡(luò)庫(kù),可用于深度學(xué)習(xí)模型的設(shè)計(jì)、調(diào)試、評(píng)估、應(yīng)用和可視化。本文將基于keras訓(xùn)練實(shí)現(xiàn)微笑識(shí)別效果,需要的可以參考一下2022-01-01
Python線程之同步機(jī)制實(shí)際應(yīng)用場(chǎng)景舉例說明
這篇文章主要給大家分享的是Python線程之同步機(jī)制實(shí)際應(yīng)用場(chǎng)景舉例說明,銀行轉(zhuǎn)賬小栗子供大家參考學(xué)習(xí),希望對(duì)你有一定的幫助2022-02-02
Python時(shí)間轉(zhuǎn)化方法超全總結(jié)
在生活和工作中,我們每個(gè)人每天都在和時(shí)間打交道。本文就為大家總結(jié)了Python實(shí)現(xiàn)時(shí)間轉(zhuǎn)化的多種方法,快來跟隨小編一起學(xué)習(xí)一下吧2022-03-03

