开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 128|回复: 2
收起左侧

[易语言] 易语言能不能实现显示器输入端切换

[复制链接]
结帖率:42% (5/12)
发表于 5 天前 | 显示全部楼层 |阅读模式   河南省驻马店市
30精币
别人用python做的  有没有易语言显示器切换输入端模块
import wmifrom monitorcontrol import get_monitors, InputSource
import customtkinter as ctk
import tkinter as tk
import json
import os
import threading
from PIL import Image, ImageTk
import pystray
from pystray import MenuItem as item
import keyboard  # 用于捕获全局热键
import sys

# 配置文件路径
CONFIG_FILE = "C:/HDMIfig.json"

# 保存输入源的编号
button_sources = {"HDMI": None, "DP": None, "USB-C": None}

# 托盘图标对象(全局变量,确保只创建一次)
tray_icon = None

# 图标路径
if getattr(sys, 'frozen', False):
    ICON_PATH = os.path.join(sys._MEIPASS, "hdmi", "hdmi.ico")
else:
    ICON_PATH = "hdmi/hdmi.ico"

# 获取显示器设备信息 (通过 WMI)
def get_display_info():
    wmi_service = wmi.WMI(namespace='wmi')
    displays = wmi_service.WmiMonitorID()
    return [display.InstanceName for display in displays]

# 列出所有可能的输入源,包括 DDC/CI 协议常用编号和厂商自定义源
def list_input_sources():
    input_sources = set()

    # 方式 1: 从 monitorcontrol 的 InputSource 枚举中获取输入源
    for source in InputSource:
        input_sources.add((source.value, source.name))

    # 方式 2: 常见输入源的硬编码列表,扩展到更多厂商常见编号
    common_sources = {
        1: "HDMI 1",
        2: "HDMI 2",
        3: "DisplayPort",
        4: "DVI",
        5: "VGA",
        6: "USB-C",
        7: "Thunderbolt",
        8: "Composite",
        9: "Component",
        10: "SCART",
        11: "S-Video",
        12: "Mini DisplayPort",
        13: "eDP",
        14: "MHL",
        15: "Wireless Display",
        16: "USB 3.0",
        17: "HDMI 3",
        18: "DisplayPort 2",
        19: "Thunderbolt 3",
    }

    for key, value in common_sources.items():
        input_sources.add((key, value))

    # 方式 3: 通过 WMI 获取设备信息
    display_info = get_display_info()
    for index, display in enumerate(display_info):
        input_sources.add((index + 100, f"Display {index + 1}: {display}"))

    return input_sources

# 切换显示器输入源
def switch_input_source(source_value):
    try:
        monitors = get_monitors()
        for monitor in monitors:
            with monitor:
                monitor.set_input_source(InputSource(source_value))
        output_textbox.insert(tk.END, f"成功切换到 {source_value} 输入源\n")
    except Exception as e:
        output_textbox.insert(tk.END, f"切换失败: {e}\n")

# 保存自定义按钮源编号并更新按钮名称
def save_source(button_name, source_value):
    button_sources[button_name] = source_value
    update_button_text(button_name)
    save_config()
    output_textbox.insert(tk.END, f"已保存 {button_name} 为输入源编号 {source_value}\n")

# 更新按钮文本
def update_button_text(button_name):
    if button_sources[button_name] is not None:
        if button_name == "HDMI":
            hdmi_button.configure(text=f"HDMI ({button_sources[button_name]})")
        elif button_name == "DP":
            dp_button.configure(text=f"DP ({button_sources[button_name]})")
        elif button_name == "USB-C":
            usbc_button.configure(text=f"USB-C ({button_sources[button_name]})")

# 获取输入框中的源编号,并在点击按钮时切换
def switch_and_save_source(button_name, entry_widget):
    # 获取当前输入框的值
    source_value = entry_widget.get()
    if source_value.isdigit():
        source_value = int(source_value)
        save_source(button_name, source_value)
        switch_input_source(source_value)
    elif button_sources[button_name] is not None:
        # 如果输入框没有手动值,则使用已保存的默认值
        switch_input_source(button_sources[button_name])
    else:
        output_textbox.insert(tk.END, "请输入有效的数字编号\n")

# 保存配置到文件
def save_config():
    with open(CONFIG_FILE, 'w') as f:
        json.dump(button_sources, f)

# 从文件加载配置
def load_config():
    global button_sources
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE, 'r') as f:
            button_sources = json.load(f)
        output_textbox.insert(tk.END, "配置已加载\n")
        # 确保加载后更新按钮名称
        update_button_text("HDMI")
        update_button_text("DP")
        update_button_text("USB-C")
    else:
        output_textbox.insert(tk.END, "没有找到配置文件,使用默认设置\n")
        # 设置默认 HDMI 和 DP 编号
        button_sources["HDMI"] = 16
        button_sources["DP"] = 1
        button_sources["USB-C"] = None
        update_button_text("HDMI")
        update_button_text("DP")
        update_button_text("USB-C")

    # 读取当前显示器的输入源
    get_current_input_source()

# 读取当前显示器的输入源
def get_current_input_source():
    try:
        monitors = get_monitors()
        for monitor in monitors:
            with monitor:
                current_source = monitor.get_input_source()
                output_textbox.insert(tk.END, f"当前输入源编号为: {current_source.value} ({current_source.name})\n")
                return current_source.value
    except Exception as e:
        output_textbox.insert(tk.END, f"无法读取当前输入源: {e}\n")
        return None

# 恢复窗口
def restore_window(icon, item):
    global tray_icon
    root.after(0, root.deiconify)
    tray_icon.stop()

# 最小化到托盘功能
def minimize_to_tray():
    global tray_icon
    root.withdraw()  # 隐藏窗口
    if tray_icon is None:  # 确保托盘图标只创建一次
        image = Image.open(ICON_PATH)
        menu = (item('打开主窗口', restore_window), item('关闭程序', quit_application))
        tray_icon = pystray.Icon("Monitor Switcher", image, "Monitor Switcher", menu)
        threading.Thread(target=tray_icon.run, daemon=True).start()

# 退出程序
def quit_application(icon=None, item=None):
    global tray_icon
    if tray_icon:
        tray_icon.stop()
    root.quit()

# 处理窗口最小化事件
def on_minimize(event):
    minimize_to_tray()

# 切换到 HDMI 的快捷键处理
def switch_to_hdmi():
    if button_sources["HDMI"] is not None:
        switch_input_source(button_sources["HDMI"])

# 切换到 DP 的快捷键处理
def switch_to_dp():
    if button_sources["DP"] is not None:
        switch_input_source(button_sources["DP"])

# 切换到 USB-C 的快捷键处理
def switch_to_usbc():
    if button_sources["USB-C"] is not None:
        switch_input_source(button_sources["USB-C"])

# 注册全局热键
def register_hotkeys():
    keyboard.add_hotkey('alt+1', switch_to_hdmi)
    keyboard.add_hotkey('alt+2', switch_to_dp)
    keyboard.add_hotkey('alt+3', switch_to_usbc)

# GUI 界面
def create_gui():
    global root
    # 初始化主窗口
    root = ctk.CTk()
    root.title("显示器输入源切换器")
    root.geometry("300x250")

    # 设置窗口图标
    root.iconbitmap(ICON_PATH)

    # 捕捉窗口最小化事件
    root.protocol("WM_DELETE_WINDOW", quit_application)  # 点击关闭时退出程序
    root.bind("<Unmap>", lambda event: on_minimize(event) if root.state() == 'iconic' else None)  # 最小化事件

    # 创建按钮和对应的输入框
    global hdmi_button, dp_button, usbc_button

    # HDMI
    hdmi_frame = ctk.CTkFrame(root)
    hdmi_frame.pack(pady=2)

    hdmi_button = ctk.CTkButton(hdmi_frame, text="HDMI", command=lambda: switch_and_save_source("HDMI", hdmi_entry))
    hdmi_button.pack(side="left", padx=1)

    hdmi_entry = ctk.CTkEntry(hdmi_frame, width=30)
    hdmi_entry.pack(side="left")

    # DP
    dp_frame = ctk.CTkFrame(root)
    dp_frame.pack(pady=2)

    dp_button = ctk.CTkButton(dp_frame, text="DP", command=lambda: switch_and_save_source("DP", dp_entry))
    dp_button.pack(side="left", padx=1)

    dp_entry = ctk.CTkEntry(dp_frame, width=30)
    dp_entry.pack(side="left")

    # USB-C
    usbc_frame = ctk.CTkFrame(root)
    usbc_frame.pack(pady=2)

    usbc_button = ctk.CTkButton(usbc_frame, text="USB-C", command=lambda: switch_and_save_source("USB-C", usbc_entry))
    usbc_button.pack(side="left", padx=1)

    usbc_entry = ctk.CTkEntry(usbc_frame, width=30)
    usbc_entry.pack(side="left")

    # 输出信息框
    global output_textbox
    output_textbox = ctk.CTkTextbox(root, height=200, width=400)
    output_textbox.pack(pady=2)

    # 列出所有可能的输入源
    output_textbox.insert(tk.END, "可能的输入源:\n")
    input_sources = list_input_sources()
    for source in input_sources:
        output_textbox.insert(tk.END, f"{source[1]} (Code: {source[0]})\n")

    # 加载配置并更新按钮文本
    load_config()

    # 注册热键
    register_hotkeys()

    root.mainloop()

if __name__ == "__main__":
    create_gui()


无标题.png

回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值无答案申请取消悬赏投诉有答案未采纳为最佳

签到天数: 11 天

发表于 5 天前 | 显示全部楼层   湖南省长沙市
使用显示器品牌SDK/CLI工具,每个品牌对硬的sdk不一样!
回复

使用道具 举报

结帖率:42% (5/12)

签到天数: 2 天

 楼主| 发表于 4 天前 | 显示全部楼层   河南省驻马店市
不需要对应把 可以使用一次后设置吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备2025452707号) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表