基于Python開發(fā)Windows屏幕控制工具
概述
在數(shù)字化辦公時(shí)代,屏幕管理已成為提升工作效率和保護(hù)眼睛健康的重要環(huán)節(jié)。今天我將分享一個(gè)基于Python和PySide6開發(fā)的Windows屏幕控制工具,它集成了一鍵息屏、亮度調(diào)節(jié)、自動息屏?xí)r間設(shè)置和全局快捷鍵等實(shí)用功能,并支持系統(tǒng)托盤運(yùn)行和開機(jī)自啟動。
本文將深入解析這個(gè)工具的實(shí)現(xiàn)原理、關(guān)鍵技術(shù)點(diǎn)和完整代碼,適合有一定Python基礎(chǔ)的開發(fā)者學(xué)習(xí)GUI開發(fā)、系統(tǒng)級操作和實(shí)用工具開發(fā)。
功能亮點(diǎn)
1.一鍵息屏功能
- 立即關(guān)閉顯示器節(jié)省能源
- 支持全局快捷鍵觸發(fā)(可自定義)
2.自動息屏?xí)r間設(shè)置
- 預(yù)設(shè)常用時(shí)間(1/5/10/15/30/60分鐘)
- 支持自定義任意分鐘數(shù)
- 永不息屏模式
3.屏幕亮度控制
- 0-100%無級調(diào)節(jié)
- 預(yù)設(shè)常用亮度檔位
- 亮度調(diào)節(jié)快捷鍵支持
4.實(shí)用附加功能
- 系統(tǒng)托盤運(yùn)行
- 開機(jī)自啟動
- 啟動時(shí)最小化
- 當(dāng)前設(shè)置實(shí)時(shí)顯示
界面展示
主界面設(shè)計(jì)

界面采用現(xiàn)代化設(shè)計(jì),包含:
- 醒目的標(biāo)題區(qū)
- 快速息屏大按鈕
- 自動息屏?xí)r間預(yù)設(shè)區(qū)
- 亮度控制滑塊
- 應(yīng)用設(shè)置面板
- 當(dāng)前設(shè)置顯示區(qū)
系統(tǒng)托盤菜單

實(shí)現(xiàn)步驟詳解
1. 環(huán)境準(zhǔn)備
# 主要依賴庫 import sys import ctypes import subprocess import winreg from PySide6.QtWidgets import (QApplication, QMainWindow, ...) from PySide6.QtCore import Qt, QTimer, QSettings
2. 亮度控制模塊
亮度調(diào)節(jié)采用了三種備選方案,確保兼容性:
class BrightnessController:
def set_brightness(self, level):
# 方法1: WMI (Windows Management Instrumentation)
try:
import wmi
w = wmi.WMI(namespace='wmi')
methods = w.WmiMonitorBrightnessMethods()[0]
methods.WmiSetBrightness(level, 0)
# 方法2: PowerShell命令
except:
script = f"$brightness = {level}; $myMonitor = Get-WmiObject..."
subprocess.run(["powershell", "-Command", script])
# 方法3: DDC/CI控制
except:
import screen_brightness_control as sbc
sbc.set_brightness(level)3. 息屏功能實(shí)現(xiàn)
使用Windows API發(fā)送消息關(guān)閉顯示器:
def turn_off_screen(self):
# 0x0112 = WM_SYSCOMMAND, 0xF170 = SC_MONITORPOWER, 2 = 關(guān)閉顯示器
ctypes.windll.user32.SendMessageW(0xFFFF, 0x0112, 0xF170, 2)
4. 息屏?xí)r間設(shè)置
通過Windows powercfg命令修改電源設(shè)置:
def set_screen_timeout(self, minutes):
if minutes == 0: # 永不息屏
subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', '0'])
else: # 設(shè)置指定時(shí)間
subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', str(minutes)])
5. 全局快捷鍵實(shí)現(xiàn)
使用QShortcut捕獲全局快捷鍵:
def setup_global_shortcut(self, key_sequence):
self.global_shortcut = QShortcut(key_sequence, self)
self.global_shortcut.activated.connect(self.turn_off_screen)
6. 開機(jī)自啟動
通過修改Windows注冊表實(shí)現(xiàn):
def toggle_autostart(self, state):
key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
if state == Qt.Checked: # 添加啟動項(xiàng)
winreg.SetValueEx(key, "ScreenController", 0, winreg.REG_SZ, exe_path)
else: # 刪除啟動項(xiàng)
winreg.DeleteValue(key, "ScreenController")
7. 系統(tǒng)托盤集成
創(chuàng)建托盤圖標(biāo)和右鍵菜單:
def setup_tray_icon(self):
self.tray_icon = QSystemTrayIcon(self)
tray_menu = QMenu()
# 添加菜單項(xiàng)
show_action = QAction("顯示主窗口", self)
screen_off_action = QAction("立即息屏", self)
# 亮度子菜單
brightness_menu = tray_menu.addMenu("屏幕亮度")
for level in [0, 25, 50, 75, 100]:
action = QAction(f"{level}%", self)
action.triggered.connect(lambda l=level: self.set_brightness_level(l))
brightness_menu.addAction(action)
關(guān)鍵代碼解析
1. 多方法亮度控制
亮度控制模塊采用了策略模式,依次嘗試三種不同的亮度調(diào)節(jié)方法:
- WMI方式:最原生的Windows管理接口
- PowerShell方式:兼容性更好的腳本方法
- DDC/CI方式:直接與顯示器通信
這種設(shè)計(jì)確保了在各種Windows環(huán)境和硬件配置下都能正常工作。
2. 設(shè)置持久化
使用QSettings實(shí)現(xiàn)配置的自動保存和加載:
# 保存設(shè)置
self.settings.setValue("shortcut", self.shortcut_edit.keySequence().toString())
# 加載設(shè)置
shortcut_string = self.settings.value("shortcut", "", type=str)
3. 管理員權(quán)限檢測
關(guān)鍵系統(tǒng)操作需要管理員權(quán)限:
def is_admin(self):
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
源碼下載
import sys
import ctypes
import subprocess
import os
import sys
import winreg
import argparse
from pathlib import Path
from PySide6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QGridLayout, QPushButton, QLabel, QLineEdit, QFrame, QMessageBox,
QGroupBox, QSpacerItem, QSizePolicy, QCheckBox, QKeySequenceEdit,
QSystemTrayIcon, QMenu, QSlider
)
from PySide6.QtCore import Qt, QTimer, QSettings, QStandardPaths
from PySide6.QtGui import QFont, QPalette, QColor, QKeySequence, QShortcut, QIcon, QPixmap, QAction
# 獲取應(yīng)用程序路徑(支持打包后的可執(zhí)行文件)
def get_app_path():
"""獲取應(yīng)用程序路徑,支持打包后的可執(zhí)行文件"""
if getattr(sys, 'frozen', False):
return Path(sys.executable).parent
else:
return Path(__file__).parent
# 獲取配置文件路徑
def get_config_path():
"""獲取配置文件路徑"""
config_dir = QStandardPaths.writableLocation(QStandardPaths.AppConfigLocation)
return Path(config_dir) / "ScreenController"
class BrightnessController:
"""屏幕亮度控制類"""
def __init__(self):
self.physical_monitors = self._get_physical_monitors()
def _get_physical_monitors(self):
"""獲取物理顯示器句柄"""
try:
from screeninfo import get_monitors
return [monitor for monitor in get_monitors() if monitor.is_primary]
except Exception as e:
print(f"獲取顯示器信息失敗: {e}")
return []
def set_brightness(self, level):
"""設(shè)置屏幕亮度(0-100)"""
try:
if not (0 <= level <= 100):
raise ValueError("亮度值必須在0-100之間")
# 方法1: 使用WMI (Windows Management Instrumentation)
try:
import wmi
w = wmi.WMI(namespace='wmi')
methods = w.WmiMonitorBrightnessMethods()[0]
methods.WmiSetBrightness(level, 0)
return True
except Exception as wmi_error:
# 方法2: 使用PowerShell命令 (適用于更多系統(tǒng))
try:
brightness = max(0, min(100, level))
script = f"""
$brightness = {brightness}
$delay = 0
$myMonitor = Get-WmiObject -Namespace root\\wmi -Class WmiMonitorBrightnessMethods
$myMonitor.WmiSetBrightness($delay, $brightness)
"""
subprocess.run(["powershell", "-Command", script], check=True, creationflags=subprocess.CREATE_NO_WINDOW)
return True
except subprocess.CalledProcessError:
# 方法3: 使用DDC/CI (需要顯示器支持)
try:
if self.physical_monitors:
import screen_brightness_control as sbc
sbc.set_brightness(level)
return True
except Exception as sbc_error:
raise Exception(f"所有亮度調(diào)節(jié)方法均失敗: WMI錯(cuò)誤: {wmi_error}, DDC/CI錯(cuò)誤: {sbc_error}")
except Exception as e:
raise Exception(f"設(shè)置亮度失敗: {str(e)}")
class ScreenController(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("??? Windows屏幕控制")
self.setFixedSize(1000, 800) # 增加窗口尺寸以容納亮度控制
# 亮度控制器
self.brightness_controller = BrightnessController()
# 設(shè)置存儲
config_path = get_config_path()
config_path.mkdir(parents=True, exist_ok=True)
settings_file = config_path / "settings.ini"
self.settings = QSettings(str(settings_file), QSettings.IniFormat)
# 全局快捷鍵
self.global_shortcut = None
self.brightness_shortcut = None
# 系統(tǒng)托盤
self.tray_icon = None
self.setup_tray_icon()
self.setup_ui()
self.setup_style()
self.load_settings()
# 定時(shí)器用于更新當(dāng)前設(shè)置
self.update_timer = QTimer()
self.update_timer.timeout.connect(self.update_current_setting)
self.update_timer.start(5000) # 每5秒更新一次
# 初始更新
self.update_current_setting()
def setup_ui(self):
"""設(shè)置用戶界面"""
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 主布局
main_layout = QVBoxLayout(central_widget)
main_layout.setSpacing(20)
main_layout.setContentsMargins(25, 25, 25, 25)
# 標(biāo)題 - 添加emoji
title_label = QLabel("??? Windows屏幕控制器")
title_font = QFont("Microsoft YaHei", 20, QFont.Bold)
title_label.setFont(title_font)
title_label.setAlignment(Qt.AlignCenter)
title_label.setStyleSheet("""
QLabel {
padding: 15px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #3498db, stop:1 #2ecc71);
border-radius: 12px;
border: 2px solid #bdc3c7;
color: white;
}
""")
main_layout.addWidget(title_label)
# 快速息屏按鈕
self.screen_off_btn = QPushButton("?? 立即息屏")
self.screen_off_btn.clicked.connect(self.turn_off_screen)
self.screen_off_btn.setFixedHeight(65)
button_font = QFont("Microsoft YaHei", 14, QFont.Bold)
self.screen_off_btn.setFont(button_font)
self.screen_off_btn.setStyleSheet("""
QPushButton {
background-color: #e74c3c;
color: white;
border: none;
border-radius: 12px;
padding: 15px;
}
QPushButton:hover {
background-color: #ec7063;
transform: scale(1.02);
}
QPushButton:pressed {
background-color: #c0392b;
}
""")
main_layout.addWidget(self.screen_off_btn)
# 分隔線
separator = QFrame()
separator.setFrameShape(QFrame.HLine)
separator.setFrameShadow(QFrame.Sunken)
separator.setStyleSheet("""
QFrame {
color: #bdc3c7;
margin: 10px 0;
}
""")
main_layout.addWidget(separator)
# 創(chuàng)建水平布局容器
horizontal_container = QWidget()
horizontal_layout = QHBoxLayout(horizontal_container)
horizontal_layout.setSpacing(20)
horizontal_layout.setContentsMargins(0, 0, 0, 0)
# 左側(cè):息屏?xí)r間設(shè)置組
settings_group = QGroupBox("?? 自動息屏?xí)r間設(shè)置")
settings_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
settings_group.setStyleSheet("""
QGroupBox {
font-weight: bold;
border: 2px solid #3498db;
border-radius: 12px;
margin-top: 10px;
padding-top: 15px;
background-color: #f8fafc;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 20px;
padding: 0 10px 0 10px;
color: #2980b9;
}
""")
settings_layout = QVBoxLayout(settings_group)
settings_layout.setSpacing(15)
# 預(yù)設(shè)時(shí)間按鈕網(wǎng)格
preset_label = QLabel("? 快速設(shè)置(分鐘):")
preset_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
preset_label.setStyleSheet("QLabel { color: #2c3e50; margin-bottom: 5px; }")
settings_layout.addWidget(preset_label)
# 第一行:1, 5, 10分鐘
preset_row1 = QWidget()
preset_layout1 = QHBoxLayout(preset_row1)
preset_layout1.setSpacing(12)
preset_layout1.setContentsMargins(0, 0, 0, 0)
time_emojis = {1: "??", 5: "?", 10: "?"}
for time_val in [1, 5, 10]:
btn = QPushButton(f"{time_emojis.get(time_val, '??')} {time_val}分鐘")
btn.clicked.connect(lambda checked=None, t=time_val: self.set_screen_timeout(t))
btn.setFixedHeight(50)
btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))
btn.setStyleSheet("""
QPushButton {
background-color: #3498db;
color: white;
border: none;
border-radius: 10px;
padding: 10px;
min-width: 90px;
}
QPushButton:hover {
background-color: #5dade2;
}
QPushButton:pressed {
background-color: #2980b9;
}
""")
preset_layout1.addWidget(btn)
settings_layout.addWidget(preset_row1)
# 第二行:15, 30, 60分鐘
preset_row2 = QWidget()
preset_layout2 = QHBoxLayout(preset_row2)
preset_layout2.setSpacing(12)
preset_layout2.setContentsMargins(0, 0, 0, 0)
time_emojis = {15: "??", 30: "??", 60: "??"}
for time_val in [15, 30, 60]:
btn = QPushButton(f"{time_emojis.get(time_val, '??')} {time_val}分鐘")
btn.clicked.connect(lambda checked=None, t=time_val: self.set_screen_timeout(t))
btn.setFixedHeight(50)
btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))
btn.setStyleSheet("""
QPushButton {
background-color: #16a085;
color: white;
border: none;
border-radius: 10px;
padding: 10px;
min-width: 90px;
}
QPushButton:hover {
background-color: #48c9b0;
}
QPushButton:pressed {
background-color: #138d75;
}
""")
preset_layout2.addWidget(btn)
settings_layout.addWidget(preset_row2)
# 添加間距
settings_layout.addItem(QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Fixed))
# 自定義時(shí)間設(shè)置
custom_label = QLabel("?? 自定義時(shí)間:")
custom_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
custom_label.setStyleSheet("QLabel { color: #2c3e50; margin-bottom: 5px; }")
settings_layout.addWidget(custom_label)
custom_widget = QWidget()
custom_layout = QHBoxLayout(custom_widget)
custom_layout.setSpacing(12)
custom_layout.setContentsMargins(0, 0, 0, 0)
self.custom_time_input = QLineEdit()
self.custom_time_input.setPlaceholderText("輸入分鐘數(shù)...")
self.custom_time_input.setFixedHeight(50)
self.custom_time_input.setFont(QFont("Microsoft YaHei", 11))
self.custom_time_input.returnPressed.connect(self.set_custom_timeout)
self.custom_time_input.setStyleSheet("""
QLineEdit {
border: 2px solid #bdc3c7;
border-radius: 10px;
padding: 12px;
background-color: white;
font-size: 11pt;
}
QLineEdit:focus {
border-color: #f39c12;
background-color: #fffde7;
}
""")
custom_layout.addWidget(self.custom_time_input, 2)
minutes_label = QLabel("? 分鐘")
minutes_label.setFont(QFont("Microsoft YaHei", 11))
minutes_label.setStyleSheet("QLabel { color: #7f8c8d; }")
custom_layout.addWidget(minutes_label)
custom_btn = QPushButton("? 設(shè)置")
custom_btn.clicked.connect(self.set_custom_timeout)
custom_btn.setFixedHeight(50)
custom_btn.setFixedWidth(100)
custom_btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))
custom_btn.setStyleSheet("""
QPushButton {
background-color: #f39c12;
color: white;
border: none;
border-radius: 10px;
padding: 10px;
}
QPushButton:hover {
background-color: #f4d03f;
}
QPushButton:pressed {
background-color: #d68910;
}
""")
custom_layout.addWidget(custom_btn)
settings_layout.addWidget(custom_widget)
# 添加間距
settings_layout.addItem(QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Fixed))
# 永不息屏按鈕
never_btn = QPushButton("?? 永不息屏")
never_btn.clicked.connect(lambda checked=None: self.set_screen_timeout(0))
never_btn.setFixedHeight(55)
never_btn.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
never_btn.setStyleSheet("""
QPushButton {
background-color: #e74c3c;
color: white;
border: none;
border-radius: 12px;
padding: 12px;
font-weight: bold;
}
QPushButton:hover {
background-color: #ec7063;
transform: scale(1.02);
}
QPushButton:pressed {
background-color: #c0392b;
}
""")
settings_layout.addWidget(never_btn)
# 將息屏?xí)r間設(shè)置組添加到左側(cè)
horizontal_layout.addWidget(settings_group)
# 中間:亮度控制組
brightness_group = QGroupBox("?? 屏幕亮度控制")
brightness_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
brightness_group.setStyleSheet("""
QGroupBox {
font-weight: bold;
border: 2px solid #f39c12;
border-radius: 12px;
margin-top: 10px;
padding-top: 15px;
background-color: #fff9e6;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 20px;
padding: 0 10px 0 10px;
color: #d35400;
}
""")
brightness_layout = QVBoxLayout(brightness_group)
brightness_layout.setSpacing(15)
# 亮度滑塊
brightness_slider_layout = QHBoxLayout()
self.brightness_slider = QSlider(Qt.Horizontal)
self.brightness_slider.setRange(0, 100)
self.brightness_slider.setValue(80)
self.brightness_slider.setTickInterval(10)
self.brightness_slider.setTickPosition(QSlider.TicksBelow)
self.brightness_slider.valueChanged.connect(self.adjust_brightness)
self.brightness_slider.setStyleSheet("""
QSlider::groove:horizontal {
height: 10px;
background: #e0e0e0;
border-radius: 5px;
}
QSlider::handle:horizontal {
width: 20px;
height: 20px;
background: #f39c12;
border-radius: 10px;
margin: -5px 0;
}
QSlider::sub-page:horizontal {
background: #f1c40f;
border-radius: 5px;
}
""")
brightness_slider_layout.addWidget(self.brightness_slider)
self.brightness_label = QLabel("80%")
self.brightness_label.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))
self.brightness_label.setFixedWidth(40)
self.brightness_label.setAlignment(Qt.AlignCenter)
brightness_slider_layout.addWidget(self.brightness_label)
brightness_layout.addLayout(brightness_slider_layout)
# 亮度預(yù)設(shè)按鈕
brightness_preset_layout = QHBoxLayout()
brightness_preset_layout.setSpacing(10)
for level in [0, 25, 50, 75, 100]:
btn = QPushButton(f"{level}%")
btn.setFixedHeight(35)
btn.setFont(QFont("Microsoft YaHei", 9))
btn.clicked.connect(lambda checked=None, l=level: self.set_brightness_level(l))
btn.setStyleSheet("""
QPushButton {
background-color: #f1c40f;
color: #34495e;
border: none;
border-radius: 8px;
padding: 5px;
}
QPushButton:hover {
background-color: #f39c12;
color: white;
}
QPushButton:pressed {
background-color: #e67e22;
}
""")
brightness_preset_layout.addWidget(btn)
brightness_layout.addLayout(brightness_preset_layout)
# 亮度快捷鍵設(shè)置
brightness_shortcut_layout = QHBoxLayout()
brightness_shortcut_label = QLabel("?? 亮度調(diào)節(jié)快捷鍵:")
brightness_shortcut_label.setFont(QFont("Microsoft YaHei", 10))
brightness_shortcut_layout.addWidget(brightness_shortcut_label)
self.brightness_shortcut_edit = QKeySequenceEdit()
self.brightness_shortcut_edit.setFixedHeight(35)
self.brightness_shortcut_edit.keySequenceChanged.connect(self.on_brightness_shortcut_changed)
brightness_shortcut_layout.addWidget(self.brightness_shortcut_edit)
brightness_layout.addLayout(brightness_shortcut_layout)
horizontal_layout.addWidget(brightness_group)
# 右側(cè):應(yīng)用設(shè)置組
app_settings_group = QGroupBox("?? 應(yīng)用設(shè)置")
app_settings_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
app_settings_group.setStyleSheet("""
QGroupBox {
font-weight: bold;
border: 2px solid #9b59b6;
border-radius: 12px;
margin-top: 15px;
padding-top: 15px;
background-color: #faf5ff;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 20px;
padding: 0 15px 0 15px;
color: #8e44ad;
}
""")
app_settings_layout = QVBoxLayout(app_settings_group)
app_settings_layout.setSpacing(20)
# 開機(jī)自啟動復(fù)選框
autostart_widget = QWidget()
autostart_layout = QHBoxLayout(autostart_widget)
autostart_layout.setContentsMargins(10, 5, 10, 5)
self.autostart_checkbox = QCheckBox("?? 開機(jī)自啟動")
self.autostart_checkbox.setFont(QFont("Microsoft YaHei", 11))
self.autostart_checkbox.stateChanged.connect(self.toggle_autostart)
self.autostart_checkbox.setStyleSheet("""
QCheckBox {
color: #2c3e50;
padding: 8px;
font-weight: 500;
}
QCheckBox::indicator {
width: 22px;
height: 22px;
}
QCheckBox::indicator:unchecked {
border: 2px solid #bdc3c7;
border-radius: 5px;
background-color: white;
}
QCheckBox::indicator:checked {
border: 2px solid #9b59b6;
border-radius: 5px;
background-color: #9b59b6;
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzIDRMNiAxMkwzIDgiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);
}
QCheckBox::indicator:hover {
border-color: #9b59b6;
}
""")
autostart_layout.addWidget(self.autostart_checkbox)
autostart_layout.addStretch()
app_settings_layout.addWidget(autostart_widget)
# 啟動時(shí)最小化復(fù)選框
minimize_widget = QWidget()
minimize_layout = QHBoxLayout(minimize_widget)
minimize_layout.setContentsMargins(10, 5, 10, 5)
self.minimize_on_start_checkbox = QCheckBox("?? 啟動時(shí)最小化到系統(tǒng)托盤")
self.minimize_on_start_checkbox.setFont(QFont("Microsoft YaHei", 11))
self.minimize_on_start_checkbox.stateChanged.connect(self.save_settings)
self.minimize_on_start_checkbox.setStyleSheet(self.autostart_checkbox.styleSheet())
minimize_layout.addWidget(self.minimize_on_start_checkbox)
minimize_layout.addStretch()
app_settings_layout.addWidget(minimize_widget)
# 快捷鍵設(shè)置
shortcut_container = QWidget()
shortcut_container_layout = QVBoxLayout(shortcut_container)
shortcut_container_layout.setContentsMargins(10, 5, 10, 5)
shortcut_container_layout.setSpacing(8)
shortcut_header = QWidget()
shortcut_header_layout = QHBoxLayout(shortcut_header)
shortcut_header_layout.setContentsMargins(0, 0, 0, 0)
shortcut_label = QLabel("?? 立即息屏快捷鍵:")
shortcut_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
shortcut_label.setStyleSheet("QLabel { color: #2c3e50; font-weight: 500; }")
shortcut_header_layout.addWidget(shortcut_label)
shortcut_header_layout.addStretch()
shortcut_container_layout.addWidget(shortcut_header)
shortcut_widget = QWidget()
shortcut_layout = QHBoxLayout(shortcut_widget)
shortcut_layout.setSpacing(12)
shortcut_layout.setContentsMargins(0, 0, 0, 0)
self.shortcut_edit = QKeySequenceEdit()
self.shortcut_edit.setFixedHeight(45)
self.shortcut_edit.setFont(QFont("Microsoft YaHei", 10))
self.shortcut_edit.keySequenceChanged.connect(self.on_shortcut_changed)
self.shortcut_edit.setStyleSheet("""
QKeySequenceEdit {
border: 2px solid #bdc3c7;
border-radius: 10px;
padding: 10px;
background-color: white;
font-size: 10pt;
}
QKeySequenceEdit:focus {
border-color: #9b59b6;
background-color: #fffde7;
}
""")
shortcut_layout.addWidget(self.shortcut_edit, 2)
clear_shortcut_btn = QPushButton("??? 清除")
clear_shortcut_btn.clicked.connect(self.clear_shortcut)
clear_shortcut_btn.setFixedHeight(45)
clear_shortcut_btn.setFixedWidth(80)
clear_shortcut_btn.setFont(QFont("Microsoft YaHei", 9, QFont.Bold))
clear_shortcut_btn.setStyleSheet("""
QPushButton {
background-color: #95a5a6;
color: white;
border: none;
border-radius: 10px;
padding: 8px;
}
QPushButton:hover {
background-color: #b2bec3;
}
QPushButton:pressed {
background-color: #7f8c8d;
}
""")
shortcut_layout.addWidget(clear_shortcut_btn)
shortcut_container_layout.addWidget(shortcut_widget)
app_settings_layout.addWidget(shortcut_container)
# 將應(yīng)用設(shè)置組添加到右側(cè)
horizontal_layout.addWidget(app_settings_group)
# 將水平布局容器添加到主布局
main_layout.addWidget(horizontal_container)
# 當(dāng)前設(shè)置顯示
self.current_setting_label = QLabel("?? 當(dāng)前設(shè)置:獲取中...")
self.current_setting_label.setFont(QFont("Microsoft YaHei", 10))
self.current_setting_label.setAlignment(Qt.AlignCenter)
self.current_setting_label.setStyleSheet("""
QLabel {
color: #7f8c8d;
padding: 15px;
background-color: #f8f9fa;
border-radius: 8px;
border: 1px solid #dee2e6;
}
""")
main_layout.addWidget(self.current_setting_label)
# 添加彈性空間
main_layout.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))
# 底部信息欄
footer_label = QLabel("??? 由創(chuàng)客白澤開發(fā) | ??? Windows屏幕控制工具 ")
footer_label.setFont(QFont("Microsoft YaHei", 8))
footer_label.setAlignment(Qt.AlignCenter)
footer_label.setStyleSheet("QLabel { color: #7f8c8d; margin-top: 10px; }")
main_layout.addWidget(footer_label)
def setup_style(self):
"""設(shè)置整體樣式"""
self.setStyleSheet("""
QMainWindow {
background-color: #ffffff;
}
QWidget {
background-color: #ffffff;
}
""")
def setup_tray_icon(self):
"""設(shè)置系統(tǒng)托盤圖標(biāo)"""
if not QSystemTrayIcon.isSystemTrayAvailable():
QMessageBox.critical(self, "系統(tǒng)托盤", "系統(tǒng)托盤不可用")
return
# 創(chuàng)建托盤圖標(biāo)
self.tray_icon = QSystemTrayIcon(self)
# 嘗試加載favicon.ico圖標(biāo)
app_path = get_app_path()
icon_path = app_path / "icon.ico"
if icon_path.exists():
icon = QIcon(str(icon_path))
else:
# 如果找不到favicon.ico,創(chuàng)建一個(gè)簡單的圖標(biāo)
pixmap = QPixmap(16, 16)
pixmap.fill(Qt.blue)
icon = QIcon(pixmap)
self.tray_icon.setIcon(icon)
# 創(chuàng)建托盤菜單
tray_menu = QMenu()
# 顯示主窗口
show_action = QAction("??? 顯示主窗口", self)
show_action.triggered.connect(self.show_main_window)
tray_menu.addAction(show_action)
# 立即息屏
screen_off_action = QAction("?? 立即息屏", self)
screen_off_action.triggered.connect(self.turn_off_screen)
tray_menu.addAction(screen_off_action)
# 亮度調(diào)節(jié)菜單
brightness_menu = tray_menu.addMenu("?? 屏幕亮度")
brightness_levels = [
("?? 0%", 0),
("?? 25%", 25),
("?? 50%", 50),
("?? 75%", 75),
("?? 100%", 100)
]
for text, level in brightness_levels:
action = QAction(text, self)
action.triggered.connect(lambda checked=None, l=level: self.set_brightness_level(l))
brightness_menu.addAction(action)
tray_menu.addSeparator()
# 退出程序
quit_action = QAction("?? 退出", self)
quit_action.triggered.connect(QApplication.instance().quit)
tray_menu.addAction(quit_action)
self.tray_icon.setContextMenu(tray_menu)
self.tray_icon.activated.connect(self.tray_icon_activated)
# 設(shè)置托盤提示
self.tray_icon.setToolTip("Windows屏幕控制器")
# 顯示托盤圖標(biāo)
self.tray_icon.show()
def tray_icon_activated(self, reason):
"""托盤圖標(biāo)被激活時(shí)的處理"""
if reason == QSystemTrayIcon.DoubleClick:
self.show_main_window()
def show_main_window(self):
"""顯示主窗口"""
self.show()
self.raise_()
self.activateWindow()
def turn_off_screen(self):
"""立即關(guān)閉屏幕"""
try:
# 發(fā)送消息關(guān)閉顯示器
ctypes.windll.user32.SendMessageW(0xFFFF, 0x0112, 0xF170, 2)
except Exception as e:
if self.isVisible():
QMessageBox.warning(self, "錯(cuò)誤", f"關(guān)閉屏幕失敗: {str(e)}")
else:
# 如果窗口不可見,通過托盤顯示消息
if self.tray_icon:
self.tray_icon.showMessage("錯(cuò)誤", f"關(guān)閉屏幕失敗: {str(e)}", QSystemTrayIcon.Warning, 3000)
def set_screen_timeout(self, minutes):
"""設(shè)置屏幕超時(shí)時(shí)間"""
try:
if minutes == 0:
message = "已設(shè)置為永不息屏"
# 永不關(guān)閉屏幕
result1 = subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', '0'],
capture_output=True, text=True, check=True,
creationflags=subprocess.CREATE_NO_WINDOW)
result2 = subprocess.run(['powercfg', '/change', 'monitor-timeout-dc', '0'],
capture_output=True, text=True, check=True,
creationflags=subprocess.CREATE_NO_WINDOW)
else:
message = f"已設(shè)置息屏?xí)r間為 {minutes} 分鐘"
# 設(shè)置指定的超時(shí)時(shí)間
result1 = subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', str(minutes)],
capture_output=True, text=True, check=True,
creationflags=subprocess.CREATE_NO_WINDOW)
result2 = subprocess.run(['powercfg', '/change', 'monitor-timeout-dc', str(minutes)],
capture_output=True, text=True, check=True,
creationflags=subprocess.CREATE_NO_WINDOW)
if self.isVisible():
QMessageBox.information(self, "成功", message)
else:
# 如果窗口不可見,通過托盤顯示消息
if self.tray_icon:
self.tray_icon.showMessage("設(shè)置成功", message, QSystemTrayIcon.Information, 3000)
self.update_current_setting()
except subprocess.CalledProcessError as e:
error_msg = f"設(shè)置失敗: {e.stderr if e.stderr else str(e)}"
if self.isVisible():
QMessageBox.warning(self, "錯(cuò)誤", error_msg)
else:
if self.tray_icon:
self.tray_icon.showMessage("錯(cuò)誤", error_msg, QSystemTrayIcon.Warning, 3000)
except FileNotFoundError:
error_msg = "找不到powercfg命令,請確保在Windows系統(tǒng)上運(yùn)行"
if self.isVisible():
QMessageBox.warning(self, "錯(cuò)誤", error_msg)
else:
if self.tray_icon:
self.tray_icon.showMessage("錯(cuò)誤", error_msg, QSystemTrayIcon.Warning, 3000)
except Exception as e:
error_msg = f"未知錯(cuò)誤: {str(e)}"
if self.isVisible():
QMessageBox.warning(self, "錯(cuò)誤", error_msg)
else:
if self.tray_icon:
self.tray_icon.showMessage("錯(cuò)誤", error_msg, QSystemTrayIcon.Warning, 3000)
def set_custom_timeout(self):
"""設(shè)置自定義超時(shí)時(shí)間"""
try:
time_str = self.custom_time_input.text().strip()
if not time_str:
QMessageBox.warning(self, "警告", "請輸入時(shí)間")
return
minutes = int(time_str)
if minutes < 0:
QMessageBox.warning(self, "警告", "時(shí)間不能為負(fù)數(shù)")
return
self.set_screen_timeout(minutes)
self.custom_time_input.clear() # 清空輸入框
except ValueError:
QMessageBox.critical(self, "錯(cuò)誤", "請輸入有效的數(shù)字")
def update_current_setting(self):
"""更新當(dāng)前設(shè)置顯示"""
try:
# 獲取當(dāng)前屏幕超時(shí)設(shè)置
result = subprocess.run(["powercfg", "/query", "SCHEME_CURRENT",
"SUB_VIDEO", "VIDEOIDLE"],
capture_output=True, text=True, check=True,
creationflags=subprocess.CREATE_NO_WINDOW)
# 解析輸出獲取當(dāng)前設(shè)置
lines = result.stdout.split('\n')
ac_timeout = None
for line in lines:
# 支持中英文輸出
if "Current AC Power Setting Index:" in line or "當(dāng)前交流電源設(shè)置索引:" in line:
try:
ac_timeout = int(line.split(':')[1].strip(), 16)
break
except (ValueError, IndexError):
continue
if ac_timeout is not None:
if ac_timeout == 0:
setting_text = "?? 當(dāng)前設(shè)置:永不息屏"
else:
minutes = ac_timeout // 60
setting_text = f"?? 當(dāng)前設(shè)置:{minutes} 分鐘后息屏"
else:
setting_text = "?? 當(dāng)前設(shè)置:解析失敗"
self.current_setting_label.setText(setting_text)
except subprocess.CalledProcessError as e:
error_detail = f"命令執(zhí)行失敗: {e.stderr if e.stderr else '未知錯(cuò)誤'}"
self.current_setting_label.setText(f"?? 當(dāng)前設(shè)置:獲取失敗 ({error_detail})")
except FileNotFoundError:
self.current_setting_label.setText("?? 當(dāng)前設(shè)置:找不到powercfg命令")
except Exception as e:
self.current_setting_label.setText(f"?? 當(dāng)前設(shè)置:異常錯(cuò)誤 ({str(e)})")
def adjust_brightness(self, value):
"""調(diào)整屏幕亮度"""
try:
self.brightness_label.setText(f"{value}%")
self.brightness_controller.set_brightness(value)
except Exception as e:
QMessageBox.warning(self, "亮度調(diào)節(jié)失敗", f"無法調(diào)整亮度: {str(e)}")
def set_brightness_level(self, level):
"""設(shè)置特定亮度級別"""
self.brightness_slider.setValue(level)
self.adjust_brightness(level)
def on_brightness_shortcut_changed(self, key_sequence):
"""亮度快捷鍵改變時(shí)的處理"""
if key_sequence.isEmpty():
return
# 檢查快捷鍵沖突
if self.check_shortcut_conflict(key_sequence):
reply = QMessageBox.question(
self, "快捷鍵沖突",
f"?? 快捷鍵 {key_sequence.toString()} 可能與其他程序沖突。\n是否仍要使用此快捷鍵?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.No:
self.brightness_shortcut_edit.clear()
return
# 設(shè)置新的快捷鍵
self.setup_brightness_shortcut(key_sequence)
self.save_settings()
QMessageBox.information(self, "成功", f"? 已設(shè)置亮度調(diào)節(jié)快捷鍵:{key_sequence.toString()}")
def setup_brightness_shortcut(self, key_sequence):
"""設(shè)置亮度調(diào)節(jié)全局快捷鍵"""
# 清除舊的快捷鍵
if self.brightness_shortcut:
self.brightness_shortcut.setEnabled(False)
self.brightness_shortcut = None
# 設(shè)置新的快捷鍵
if not key_sequence.isEmpty():
self.brightness_shortcut = QShortcut(key_sequence, self)
self.brightness_shortcut.activated.connect(self.toggle_brightness)
def toggle_brightness(self):
"""切換亮度預(yù)設(shè)"""
current = self.brightness_slider.value()
if current >= 75:
self.set_brightness_level(25)
elif current >= 25:
self.set_brightness_level(0)
else:
self.set_brightness_level(75)
def is_admin(self):
"""檢查是否以管理員權(quán)限運(yùn)行"""
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def toggle_autostart(self, state):
"""切換開機(jī)自啟動"""
try:
key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
app_name = "WindowsScreenController"
if state == Qt.Checked:
# 添加到注冊表
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_SET_VALUE) as key:
if getattr(sys, 'frozen', False):
# 打包后的可執(zhí)行文件,添加啟動時(shí)最小化參數(shù)
exe_path = f'"{sys.executable}" --minimized'
else:
# Python腳本
exe_path = sys.executable
script_path = os.path.abspath(__file__)
exe_path = f'"{exe_path}" "{script_path}" --minimized'
winreg.SetValueEx(key, app_name, 0, winreg.REG_SZ, exe_path)
QMessageBox.information(self, "成功", "? 已啟用開機(jī)自啟動")
else:
# 從注冊表刪除
try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_SET_VALUE) as key:
winreg.DeleteValue(key, app_name)
QMessageBox.information(self, "成功", "? 已禁用開機(jī)自啟動")
except FileNotFoundError:
pass # 鍵不存在,無需刪除
self.save_settings()
except PermissionError:
QMessageBox.warning(self, "錯(cuò)誤", "? 權(quán)限不足,無法修改注冊表啟動項(xiàng)")
# 恢復(fù)復(fù)選框狀態(tài)
self.autostart_checkbox.setChecked(not state)
except Exception as e:
QMessageBox.critical(self, "錯(cuò)誤", f"?? 設(shè)置開機(jī)自啟動失?。簕str(e)}")
# 恢復(fù)復(fù)選框狀態(tài)
self.autostart_checkbox.setChecked(not state)
def check_autostart_status(self):
"""檢查開機(jī)自啟動狀態(tài)"""
try:
key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
app_name = "WindowsScreenController"
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_READ) as key:
try:
winreg.QueryValueEx(key, app_name)
return True
except FileNotFoundError:
return False
except Exception:
return False
def on_shortcut_changed(self, key_sequence):
"""快捷鍵改變時(shí)的處理"""
if key_sequence.isEmpty():
return
# 檢查快捷鍵沖突
if self.check_shortcut_conflict(key_sequence):
reply = QMessageBox.question(
self, "快捷鍵沖突",
f"?? 快捷鍵 {key_sequence.toString()} 可能與其他程序沖突。\n是否仍要使用此快捷鍵?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.No:
self.shortcut_edit.clear()
return
# 設(shè)置新的快捷鍵
self.setup_global_shortcut(key_sequence)
self.save_settings()
QMessageBox.information(self, "成功", f"? 已設(shè)置快捷鍵:{key_sequence.toString()}")
def check_shortcut_conflict(self, key_sequence):
"""檢查快捷鍵沖突(簡單檢查常見系統(tǒng)快捷鍵)"""
key_string = key_sequence.toString().lower()
# 常見的系統(tǒng)快捷鍵
system_shortcuts = [
"ctrl+c", "ctrl+v", "ctrl+x", "ctrl+z", "ctrl+y", "ctrl+a", "ctrl+s",
"ctrl+alt+del", "ctrl+shift+esc", "alt+tab", "alt+f4", "win+l",
"win+d", "win+r", "win+e", "win+i", "win+x", "ctrl+alt+t",
"print screen", "alt+print screen", "ctrl+print screen"
]
return key_string in system_shortcuts
def setup_global_shortcut(self, key_sequence):
"""設(shè)置全局快捷鍵"""
# 清除舊的快捷鍵
if self.global_shortcut:
self.global_shortcut.setEnabled(False)
self.global_shortcut = None
# 設(shè)置新的快捷鍵
if not key_sequence.isEmpty():
self.global_shortcut = QShortcut(key_sequence, self)
self.global_shortcut.activated.connect(self.turn_off_screen)
def clear_shortcut(self):
"""清除快捷鍵"""
self.shortcut_edit.clear()
if self.global_shortcut:
self.global_shortcut.setEnabled(False)
self.global_shortcut = None
self.save_settings()
QMessageBox.information(self, "成功", "??? 已清除快捷鍵")
def save_settings(self):
"""保存設(shè)置"""
self.settings.setValue("autostart", self.autostart_checkbox.isChecked())
self.settings.setValue("minimize_on_start", self.minimize_on_start_checkbox.isChecked())
self.settings.setValue("shortcut", self.shortcut_edit.keySequence().toString())
self.settings.setValue("brightness_shortcut", self.brightness_shortcut_edit.keySequence().toString())
self.settings.setValue("brightness_level", self.brightness_slider.value())
def load_settings(self):
"""加載設(shè)置"""
# 加載開機(jī)自啟動狀態(tài)
autostart_status = self.check_autostart_status()
self.autostart_checkbox.setChecked(autostart_status)
# 加載其他設(shè)置
minimize_on_start = self.settings.value("minimize_on_start", False, type=bool)
self.minimize_on_start_checkbox.setChecked(minimize_on_start)
shortcut_string = self.settings.value("shortcut", "", type=str)
if shortcut_string:
key_sequence = QKeySequence(shortcut_string)
self.shortcut_edit.setKeySequence(key_sequence)
self.setup_global_shortcut(key_sequence)
brightness_shortcut_string = self.settings.value("brightness_shortcut", "", type=str)
if brightness_shortcut_string:
key_sequence = QKeySequence(brightness_shortcut_string)
self.brightness_shortcut_edit.setKeySequence(key_sequence)
self.setup_brightness_shortcut(key_sequence)
brightness_level = self.settings.value("brightness_level", 80, type=int)
self.brightness_slider.setValue(brightness_level)
self.brightness_label.setText(f"{brightness_level}%")
# 如果設(shè)置了啟動時(shí)最小化,則隱藏到托盤
if minimize_on_start:
self.hide()
def showEvent(self, event):
"""窗口顯示時(shí)檢查權(quán)限"""
super().showEvent(event)
if not self.is_admin():
QMessageBox.warning(self, "權(quán)限提示",
"?? 建議以管理員權(quán)限運(yùn)行此程序以確保所有功能正常工作")
def closeEvent(self, event):
"""關(guān)閉事件處理"""
if self.tray_icon and self.tray_icon.isVisible():
# 如果托盤圖標(biāo)可見,隱藏到托盤而不是退出
self.hide()
event.ignore()
if not hasattr(self, '_tray_message_shown'):
self.tray_icon.showMessage(
"程序已最小化到托盤",
"?? 程序仍在后臺運(yùn)行,雙擊托盤圖標(biāo)可重新打開",
QSystemTrayIcon.Information,
3000
)
self._tray_message_shown = True
else:
self.save_settings()
event.accept()
def main():
"""主函數(shù)"""
# 解析命令行參數(shù)
parser = argparse.ArgumentParser(description='Windows屏幕控制器')
parser.add_argument('--minimized', action='store_true', help='啟動時(shí)最小化到系統(tǒng)托盤')
args = parser.parse_args()
app = QApplication(sys.argv)
# 設(shè)置應(yīng)用程序樣式
app.setStyle('Fusion')
# 設(shè)置應(yīng)用程序信息
app.setApplicationName("Windows屏幕控制器")
app.setApplicationVersion("2.0")
app.setOrganizationName("ScreenController")
# 設(shè)置應(yīng)用程序圖標(biāo)
app_path = get_app_path()
icon_path = app_path / "favicon.ico"
if icon_path.exists():
app.setWindowIcon(QIcon(str(icon_path)))
window = ScreenController()
# 如果指定了--minimized參數(shù)或設(shè)置了啟動時(shí)最小化,則不顯示主窗口
if args.minimized or window.minimize_on_start_checkbox.isChecked():
# 不顯示主窗口,直接最小化到托盤
pass
else:
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
# 檢查并安裝必要的依賴
try:
import wmi
import screeninfo
import screen_brightness_control
except ImportError:
print("正在安裝必要的依賴庫...")
try:
import pip
pip.main(['install', 'wmi', 'screeninfo', 'screen-brightness-control'])
except:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'wmi', 'screeninfo', 'screen-brightness-control'])
main()
項(xiàng)目總結(jié)
這個(gè)Windows屏幕控制工具通過精心設(shè)計(jì)的UI和穩(wěn)健的后臺實(shí)現(xiàn),解決了日常使用中的多個(gè)痛點(diǎn):
- 一鍵操作:告別繁瑣的系統(tǒng)設(shè)置路徑
- 全局快捷鍵:隨時(shí)隨地快速息屏
- 亮度精細(xì)控制:保護(hù)眼睛健康
- 無感運(yùn)行:系統(tǒng)托盤常駐不打擾
技術(shù)亮點(diǎn):
- 多方法兼容的亮度控制
- 完善的異常處理機(jī)制
- 符合Windows應(yīng)用規(guī)范的設(shè)置存儲
- 優(yōu)雅的系統(tǒng)托盤集成
擴(kuò)展方向:
- 添加多顯示器獨(dú)立控制
- 實(shí)現(xiàn)根據(jù)時(shí)間自動調(diào)整亮度
- 增加使用統(tǒng)計(jì)和提醒功能
使用建議
- 建議以管理員權(quán)限運(yùn)行以獲得完整功能
- 設(shè)置開機(jī)自啟動+最小化,實(shí)現(xiàn)無感運(yùn)行
- 為息屏功能設(shè)置順手的全局快捷鍵(如Ctrl+Alt+L)
到此這篇關(guān)于基于Python開發(fā)Windows屏幕控制工具的文章就介紹到這了,更多相關(guān)Python Windows屏幕控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Django默認(rèn)的Auth權(quán)限管理系統(tǒng)
本文主要介紹了如何使用Django默認(rèn)的Auth權(quán)限管理系統(tǒng),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
使用python將excel數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫過程詳解
這篇文章主要介紹了使用python將excel數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
Python實(shí)現(xiàn)識別手寫數(shù)字大綱
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)識別手寫數(shù)字的大綱,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Anaconda中導(dǎo)出環(huán)境的實(shí)現(xiàn)步驟
在 Anaconda 中導(dǎo)出環(huán)境是一種常用的做法,可以將當(dāng)前的環(huán)境配置導(dǎo)出到一個(gè)文件中,本文主要介紹了Anaconda中導(dǎo)出環(huán)境的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值2024-05-05
Django如何使用asyncio協(xié)程和ThreadPoolExecutor多線程
這篇文章主要介紹了Django如何使用asyncio協(xié)程和ThreadPoolExecutor多線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
Pandas中`ValueError: cannot reindex from
在Pandas中,ValueError: cannot reindex from a duplicate axis錯(cuò)誤通常發(fā)生在嘗試對包含重復(fù)索引的DataFrame或Series進(jìn)行重新索引(reindex)時(shí),所以本文介紹了Pandas中`ValueError: cannot reindex from a duplicate axis`錯(cuò)誤分析及解決辦法,需要的朋友可以參考下2024-07-07

