欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

厂商电脑登记 python 代码 冉自己亲自做的 有大用 有大大用

import os
import subprocess
import tkinter as tk
from tkinter import messagebox, font, ttk
import socket
import platform

import pymssql
from datetime import datetime
import psutil

# --- 全局配置 ---
current_time = datetime.now()
server = "192.168.2.39"
user = "aaaaa"
password = "bbbbb"
database = "cccccc"
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
WRDLV4_EXE_PATH = r"C:\Windows\System32\wrdlv4.exe"
# 数据库表名
TABLE_NAME = "computer_V"

# 默认值为 "是" 的选项
DEFAULT_YES = "是"
DEFAULT_NO = "否"
DEFAULT_SCAN_STATUS_OPTIONS = [DEFAULT_YES, DEFAULT_NO]
DEFAULT_INSTALLED_STATUS_OPTIONS = [DEFAULT_YES, DEFAULT_NO]
DEFAULT_USB_STATUS_OPTIONS = [DEFAULT_YES, DEFAULT_NO]
DEFAULT_FIREWALL_STATUS_OPTIONS = [DEFAULT_YES, DEFAULT_NO]

# --- 自动获取系统信息的函数 ---

def insert_one(row_data):
    """
    将单条数据插入或更新到指定的数据库表。
    如果 mac_address 存在,则更新该行;否则插入新行。

    参数:
        row_data (list/tuple): 包含所有字段数据的有序序列。
                                顺序必须与 SQL INSERT/UPDATE 语句中的列对应。

    返回值:
        0: 插入/更新成功
        str (错误信息): 插入/更新失败
    """
    # 确保所有数据都是字符串,以防止 pymssql 错误
    # 假设 row_data 的顺序与数据库表的字段顺序一致
    # 并且我们已经定义了常量来存储这些字段名
    # 这里为了演示,直接使用解包
    try:
        (mac_address, department, hostname, system_type, system_version,
         entry_time_str,emp_vname,
         emp_name, emp_id, area, ip_address, ip_guard_status,
         virus_scan_status, antivirus_installed_status, usb_disabled_status, firewall_enabled_status) = row_data
    except ValueError as e:
        return f"数据格式错误,所需字段数量不匹配: {e}"

    # 确保所有字段都是字符串,特别是可能包含 None 的字段
    str_row_data = [str(item) if item is not None else "" for item in row_data]

    conn = None
    try:
        conn = pymssql.connect(server, user, password, database)
        cursor = conn.cursor()

        # --------------- 数据库操作 ---------------
        # 1. 尝试更新
        #    注意:SQLAlchemy or ORM 可以更方便地管理这些,但直接使用 pymssql
        #    需要手动处理。这里使用占位符 %s。
        update_sql = f"""
        UPDATE {TABLE_NAME}
        SET ICTDRI = %s,
            hostname = %s,
            system_type = %s,
            system_version = %s,
            entry_time = %s,
            emp = %s,         -- 厂商姓名
            emp_id = %s,      -- 厂商ID (原来是 emp, 假定 emp_id 是新加的,或 emp 含义改变)
            area = %s,        -- 厂商电话
            ip_address = %s,  -- 新增加的 IP 地址
            ip_guard = %s,    -- 新增加的 IP Guard 状态
            virus_scan_status = %s, -- 新的字段名
            antivirus_installed_status = %s, -- 新的字段名
            usb_disabled_status = %s, -- 新的字段名
            firewall_enabled_status = %s, -- 新的字段名
            vendorname = %s
        WHERE mac_address = %s
        """
        # 参数顺序需要与 UPDATE SET 后面的列顺序一致,并且最后是 WHERE 子句的条件
        update_params = (department, hostname, system_type, system_version,
                         entry_time_str,emp_id,
                         emp_name,  area, ip_address, ip_guard_status,
                         virus_scan_status, antivirus_installed_status, usb_disabled_status, firewall_enabled_status,emp_vname,
                         mac_address) # 最后一位是 WHERE mac_address = %s

        cursor.execute(update_sql, update_params)

        if cursor.rowcount == 0:
            # 2. 如果没有行被更新,说明 mac_address 不存在,则插入
            insert_sql = f"""
            INSERT INTO {TABLE_NAME} (
                mac_address, ICTDRI, hostname, system_type, system_version,
                entry_time, emp, emp_id, area, ip_address, ip_guard,
                virus_scan_status, antivirus_installed_status, usb_disabled_status, firewall_enabled_status,vendorname
            )
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            # 参数顺序必须与 INSERT INTO (...) 后面的列顺序一致
            insert_params = (mac_address, department, hostname, system_type, system_version,
                             entry_time_str,emp_id,
                             emp_name, area, ip_address, ip_guard_status,
                             virus_scan_status, antivirus_installed_status, usb_disabled_status, firewall_enabled_status,emp_vname)

            cursor.execute(insert_sql, insert_params)
            conn.commit()
            return 0  # 插入成功
        else:
            conn.commit()
            return 0  # 更新成功

    except pymssql.Error as e:
        if conn:
            conn.rollback()
        return f"数据库错误: {e}"
    except Exception as e:
        if conn:
            conn.rollback()
        return f"其他错误: {e}"
    finally:
        if conn:
            try:
                cursor.close()
            except Exception:
                return "关闭游标错误"
            try:
                conn.close()
            except Exception:
                return "关闭连接错误"


def get_mac_address():
    """
    获取所有网络接口的 MAC 地址。
    返回一个字符串,其中包含所有 MAC 地址,每个地址占一行。
    """
    mac_info = []
    try:
        interfaces = psutil.net_if_addrs()
        for interface_name, addresses in interfaces.items():
            for address in addresses:
                if address.family == psutil.AF_LINK:  # AF_LINK is the layer 2 address family (MAC address)
                    mac_info.append(f"{interface_name}: {address.address}")
                    break  # Found a MAC address for this interface, move to the next interface
    except Exception as e:
        print(f"获取MAC地址时发生错误: {e}")
        return "获取MAC地址失败"
    return "\n".join(mac_info) if mac_info else "未找到MAC地址"


def get_ip_address():
    """
    获取本机 IP 地址(连接外部网络的主 IP)。
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        # 尝试连接一个外部地址,这样可以获取到路由出去的IP
        # Google's public DNS server is commonly used for this.
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception as e:
        print(f"获取IP地址时发生错误: {e}")
        return "未能获取IP地址"


def get_hostname():
    """
    获取计算机名。
    """
    try:
        return socket.gethostname()
    except Exception as e:
        print(f"获取主机名时发生错误: {e}")
        return "未能获取主机名"


def get_system_os_info():
    """
    获取系统类型和版本信息。
    """
    system_platform = platform.system().lower()
    release = platform.release() # e.g., '10', '11', '22.0.0' for macOS
    version_details = platform.version() # e.g., '10.0.19045.3996' for Windows, 'Darwin Kernel Version 23.1.0' for macOS

    # --- 系统类型 ---
    if 'windows' in system_platform:
        system_type = 'Windows'
    elif 'darwin' in system_platform:
        system_type = 'macOS'
    else:
        system_type = f'Other ({system_platform.capitalize()})'

    # --- 版本信息 ---
    friendly_version_name = release # Default to the release identifier

    if system_type == 'Windows':
        try:
            # Extract major.minor.build.revision. For example, on Windows 10/11: 10.0.19045.3996
            parts = version_details.split('.')
            if len(parts) >= 3:
                os_build = int(parts[2]) # Extract the OS Build number

                # Mapping OS Builds to Windows versions (approximations)
                if release == '10': # Windows 10
                    if os_build >= 22621: friendly_version_name = "Windows 11 Equivalent (≥ 22H2)" # Later builds might be Win11 compatible on older hardware
                    elif os_build >= 19045: friendly_version_name = "Windows 10 22H2"
                    elif os_build >= 19044: friendly_version_name = "Windows 10 21H2"
                    elif os_build >= 19043: friendly_version_name = "Windows 10 21H1"
                    elif os_build >= 19042: friendly_version_name = "Windows 10 20H2"
                    elif os_build >= 19041: friendly_version_name = "Windows 10 2004"
                    else: friendly_version_name = f"Windows 10 (Build {os_build})"
                elif release == '11': # Windows 11
                    if os_build >= 22631: friendly_version_name = "Windows 11 23H2"
                    elif os_build >= 22621: friendly_version_name = "Windows 11 22H2"
                    elif os_build >= 22000: friendly_version_name = "Windows 11 21H2"
                    else: friendly_version_name = f"Windows 11 (Build {os_build})"
                else: # Older Windows versions
                    friendly_version_name = f"Windows {release} (Build {os_build})"
            else:
                friendly_version_name = f"Windows {release} (Unknown Build)"
        except (ValueError, IndexError):
            friendly_version_name = f"Windows {release} (Detailed: {version_details})" # Fallback if parsing fails

    elif system_type == 'macOS':
        # platform.release() for macOS returns Darwin kernel version like '23.1.0'
        # We can try to map this to macOS version names.
        try:
            major_kernel_version = int(release.split('.')[0])
            if major_kernel_version >= 23:
                friendly_version_name = "macOS Sonoma"
            elif major_kernel_version == 22:
                friendly_version_name = "macOS Ventura"
            elif major_kernel_version == 21:
                friendly_version_name = "macOS Monterey"
            elif major_kernel_version == 20:
                friendly_version_name = "macOS Big Sur"
            # Add more mappings if needed
            else:
                friendly_version_name = f"macOS (Kernel {major_kernel_version})"
        except (ValueError, IndexError):
            friendly_version_name = f"macOS (Kernel {release})"

    # Return friendly name and the detailed version string
    return system_type, friendly_version_name, version_details

# --- Tkinter 界面相关函数 ---

def submit_data():

    """
    提交按钮点击时调用的函数。
    获取所有输入框的内容并插入/更新数据库。
    """
    # 获取自动填充的信息
    mac_address = text_mac_address.get("1.0", tk.END).strip()
    # MAC 地址可能有多个,这里我们只取第一行作为主MAC地址
    # mac_address = mac_address_text.split('\n')[0].split(': ')[-1] if mac_address_text else ""

    department = entry_DRI.get().strip()
    hostname = entry_hostname.get().strip()
    system_type = entry_system_type.get().strip()
    system_version = entry_system_version.get().strip()
    entry_time_str = entry_today.get().strip()
    emp_name = entry_emp_name.get().strip() # 厂商姓名
    emp_vname = entry_emp_vname.get().strip()  # 厂商姓名
    emp_id = entry_emp_id.get().strip()      # 厂商ID (原 emp)
    area = entry_area.get().strip()          # 厂商电话
    ip_address = entry_ip_address.get().strip()
    ip_guard_status = combo_ip_guard.get() # 使用 Combobox 的当前值

    virus_scan_status = combo_ntivirus_scan.get()
    antivirus_installed_status = combo_antivirus_installed.get()
    usb_disabled_status = combo_usb_disabled.get()
    firewall_enabled_status = combo_firewall_enabled.get()
    if not emp_name or not emp_vname or not emp_id or not area or not department or not mac_address or not hostname:
        messagebox.showwarning("输入警告", "缺少必填项!需要全部填写完整")
        return
    # 准备要插入的数据列表
    row_data = [
        mac_address,
        department,
        hostname,
        system_type,
        system_version,
        entry_time_str,
        emp_name,
        emp_vname,
        emp_id,
        area,
        ip_address,
        ip_guard_status,
        virus_scan_status,
        antivirus_installed_status,
        usb_disabled_status,
        firewall_enabled_status
    ]


    # 插入或更新数据
    result = insert_one(row_data)

    if result == 0:
        messagebox.showinfo("提交成功", "数据已成功提交!")
        # 提交后重置部分字段
        reset_manual_fields()
        # 重新填充自动字段 (例如MAC, Hostname, OS信息)
        populate_auto_fields()
    else:
        messagebox.showerror("提交失败", result) # 使用 errorbox 显示错误信息


def reset_manual_fields():
    """
    清空手动输入的字段。
    """
    entry_DRI.delete(0, tk.END)
    entry_emp_name.delete(0, tk.END)
    entry_emp_vname.delete(0, tk.END)
    entry_emp_id.delete(0, tk.END)
    entry_area.delete(0, tk.END)
    # IP地址和IP Guard由GUI选项决定,不在此清空
    # 状态选择框会通过populate_auto_fields和default值恢复


def firewallinfo():
    """
    检查Windows防火墙状态(仅考虑专用和公用配置文件)。
    如果专用和公用配置文件都启用,返回 1。
    否则(任何一个关闭),返回 0。
    """
    try:
        # 使用netsh命令检查Windows防火墙状态
        # 指定encoding='utf-8',通常在现代Windows环境下更通用。
        # 如果遇到乱码,再尝试回退到'cp936'或'gbk'
        result = subprocess.run(
            ["netsh", "advfirewall", "show", "allprofiles", "state"],
            capture_output=True, text=True, encoding="cp936"  # <<< 修改此处
            # encoding="cp936" # 如果 utf-8 乱码,可以尝试这个
        )

        output = result.stdout
        print("--- netsh output ---") # 打印原始输出以供调试
        print(output)
        print("--------------------")

        # 将输出按行分割,方便逐行处理
        lines = output.splitlines()

        # 初始化状态标志
        private_enabled = False
        public_enabled = False

        # 遍历每一行来查找专用和公用配置文件的状态
        for i, line in enumerate(lines):
            # 查找“专用配置文件”
            if "专用配置文件" in line or 'Private Profile Settings:' in line:
                # 检查下一行是否包含“状态”和“启用”或“ON”
                if i + 2 < len(lines) and ("状态" in lines[i+2] or "State" in lines[i+2]):
                    status_line = lines[i+2] # 状态值通常在“状态”行之后(可能隔一行)
                    if "启用" in status_line or "ON" in status_line.upper():
                        private_enabled = True
                    else:
                        private_enabled = False # Explicitly set to False if not enabled

            # 查找“公用配置文件”
            elif "公用配置文件" in line or 'Public Profile Settings:' in line:
                # 检查下一行是否包含“状态”和“启用”或“ON”
                if i + 2 < len(lines) and ("状态" in lines[i+2] or "State" in lines[i+2]):
                    status_line = lines[i+2] # 状态值通常在“状态”行之后(可能隔一行)
                    if "启用" in status_line or "ON" in status_line.upper():
                        public_enabled = True
                    else:
                        public_enabled = False # Explicitly set to False if not enabled

        # 判断最终结果:只有当专用和公用都启用时才返回 1
        if private_enabled and public_enabled:
            print("Private and Public profiles are ENABLED.")
            return 1
        else:
            print(f"Private enabled: {private_enabled}, Public enabled: {public_enabled}. At least one is OFF. Returning 0.")
            return 0

    except FileNotFoundError:
        print("Error: 'netsh' command not found. Please ensure it's in your PATH.")
        return 0
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        return 0
def ipguardinfo():
    """
    检测 C:\Windows\System32\wrdlv4.exe 是否存在。
    如果存在,返回 1。
    如果不存在,返回 0。
    """
    if os.path.exists(WRDLV4_EXE_PATH):
        print(f"'{WRDLV4_EXE_PATH}' found.")
        return 1
    else:
        print(f"'{WRDLV4_EXE_PATH}' not found.")
        return 0
def populate_auto_fields():
    """
    在窗口启动时自动填充字段。
    """
    # 填充MAC地址 (所有发现的MAC地址,每行一个)
    auto_mac_info = get_mac_address()
    text_mac_address.delete("1.0", "end")
    text_mac_address.insert("1.0", auto_mac_info)

    # 填充IP地址
    auto_ip = get_ip_address()
    entry_ip_address.delete(0, tk.END)
    entry_ip_address.insert(0, auto_ip)
    # entry_ip_address.config(state='normal') # Make it editable if needed, or leave readonly

    # 填充计算机名
    auto_hostname = get_hostname()
    entry_hostname.delete(0, tk.END)
    entry_hostname.insert(0, auto_hostname)
    # entry_hostname.config(state='readonly') # Can be readonly if auto-filled

    # 填充系统类型和版本
    auto_system_type, auto_sys_friendly, auto_sys_detailed = get_system_os_info()
    entry_system_type.delete(0, tk.END)
    entry_system_type.insert(0, auto_system_type)
    # entry_system_type.config(state='readonly')

    full_system_version_display = f"{auto_sys_friendly} ({auto_sys_detailed})"
    entry_system_version.delete(0, tk.END)
    entry_system_version.insert(0, full_system_version_display)
    # entry_system_version.config(state='readonly')

    # --- 填充预设的默认值 ---
    # 登记时间
    entry_today.delete(0, tk.END)
    entry_today.insert(0, formatted_time) # Use the globally defined formatted_time

    # 状态选择框 (Combobox) 的默认值
    if ipguardinfo():
        combo_ip_guard.set(DEFAULT_YES)
    else:
        combo_ip_guard.set(DEFAULT_NO)
    combo_ntivirus_scan.set(DEFAULT_YES)
    combo_antivirus_installed.set(DEFAULT_YES)
    combo_usb_disabled.set(DEFAULT_YES)
    if firewallinfo():
        combo_firewall_enabled.set(DEFAULT_YES)
    else:
        combo_firewall_enabled.set(DEFAULT_NO)
# --- GUI 布局和样式 ---

def center_window(window):
    """
    使 Tkinter 窗口在屏幕中心显示。
    """
    window.update_idletasks()  # 确保窗口尺寸是确定的
    width = window.winfo_width()
    height = window.winfo_height()
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()
    x = (screen_width // 2) - (width // 2)
    y = (screen_height // 2) - (height // 2)
    window.geometry(f'{width}x{height}+{x}+{y}')

# --- GUI 主程序 ---
root = tk.Tk()
root.title("设备信息录入系统")

# --- 字体设置 ---
# 定义一个大写字体,用于标签和输入框
label_font_size = 12 # 调整字体大小
input_font_size = 12
button_font_size = 14

# 调整整个界面的字体大小(可选,如果需要的话)
style = ttk.Style()
style.configure("TLabel", font=("Arial", label_font_size))
style.configure("TEntry", font=("Arial", input_font_size))
style.configure("TButton", font=("Arial", button_font_size))
style.configure("TCombobox", font=("Arial", input_font_size))

# 主框架
main_frame = tk.Frame(root, padx=20, pady=20, bg="#f0f0f0") # 添加背景色
main_frame.pack(expand=True, fill="both")

# --- Grid 配置 ---
# configure column weights so entry widgets expand
main_frame.columnconfigure(1, weight=1) # Entry widgets will expand horizontally

# --- Row 0: 登记时间 ---
tk.Label(main_frame, text="登记时间:", font=("Arial", label_font_size)).grid(row=0, column=0, sticky="w", pady=5)
entry_today = tk.Entry(main_frame, width=40, font=("Arial", input_font_size), bg="#e0e0e0", relief="sunken") # 浅灰色背景,凹陷边框
entry_today.grid(row=0, column=1, sticky="ew", pady=5) # sticky="ew" 让entry随列扩展

# --- Row 1: IP地址 ---
tk.Label(main_frame, text="IP 地址:", font=("Arial", label_font_size)).grid(row=1, column=0, sticky="w", pady=5)
entry_ip_address = tk.Entry(main_frame, width=40, font=("Arial", input_font_size), bg="#e0e0e0", relief="sunken")
entry_ip_address.grid(row=1, column=1, sticky="ew", pady=5)

# --- Row 2: MAC 地址 ---
tk.Label(main_frame, text="MAC 地址:", font=("Arial", label_font_size)).grid(row=2, column=0, sticky="w", pady=5)
text_mac_address = tk.Text(main_frame, width=40, height=2, font=("Arial", input_font_size), wrap="word", borderwidth=2,bg="#e0e0e0", relief="sunken")
text_mac_address.grid(row=2, column=1, sticky="nsew", pady=5) #nsew for expand in all directions

# --- Row 3: 计算机名 ---
tk.Label(main_frame, text="计算机名:", font=("Arial", label_font_size)).grid(row=3, column=0, sticky="w", pady=5)
entry_hostname = tk.Entry(main_frame, width=40, font=("Arial", input_font_size), bg="#e0e0e0", relief="sunken")
entry_hostname.grid(row=3, column=1, sticky="ew", pady=5)

# --- Row 4: 系统类型 ---
tk.Label(main_frame, text="系统类型:", font=("Arial", label_font_size)).grid(row=4, column=0, sticky="w", pady=5)
entry_system_type = tk.Entry(main_frame, width=40, font=("Arial", input_font_size), bg="#e0e0e0", relief="sunken")
entry_system_type.grid(row=4, column=1, sticky="ew", pady=5)

# --- Row 5: 系统版本 ---
tk.Label(main_frame, text="系统版本:", font=("Arial", label_font_size)).grid(row=5, column=0, sticky="w", pady=5)
entry_system_version = tk.Entry(main_frame, width=40, font=("Arial", input_font_size), bg="#e0e0e0", relief="sunken")
entry_system_version.grid(row=5, column=1, sticky="ew", pady=5)

tk.Label(main_frame, text="厂商名称:", font=("Arial", label_font_size)).grid(row=6, column=0, sticky="w", pady=5)
entry_emp_vname = tk.Entry(main_frame, width=40, font=("Arial", input_font_size))
entry_emp_vname.grid(row=6, column=1, sticky="ew", pady=5)

# --- Row 6: 厂商姓名 ---
tk.Label(main_frame, text="厂商姓名:", font=("Arial", label_font_size)).grid(row=7, column=0, sticky="w", pady=5)
entry_emp_name = tk.Entry(main_frame, width=40, font=("Arial", input_font_size))
entry_emp_name.grid(row=7, column=1, sticky="ew", pady=5)

# --- Row 7: 厂商ID (原 emp) ---
tk.Label(main_frame, text="厂商简称:", font=("Arial", label_font_size)).grid(row=8, column=0, sticky="w", pady=5)
entry_emp_id = tk.Entry(main_frame, width=40, font=("Arial", input_font_size))
entry_emp_id.grid(row=8, column=1, sticky="ew", pady=5)

# --- Row 8: 厂商电话/联系方式 ---
tk.Label(main_frame, text="厂商电话:", font=("Arial", label_font_size)).grid(row=9, column=0, sticky="w", pady=5)
entry_area = tk.Entry(main_frame, width=40, font=("Arial", input_font_size))
entry_area.grid(row=9, column=1, sticky="ew", pady=5)

# --- Row 9: IT部门/第三方(如ICT DRI) ---
tk.Label(main_frame, text="ICT DRI:", font=("Arial", label_font_size)).grid(row=10, column=0, sticky="w", pady=5)
entry_DRI = tk.Entry(main_frame, width=40, font=("Arial", input_font_size))
entry_DRI.grid(row=10, column=1, sticky="ew", pady=5)

# --- Row 10: IP Guard ---
tk.Label(main_frame, text="IP Guard是否安装:", font=("Arial", label_font_size)).grid(row=11, column=0, sticky="w", pady=5)
combo_ip_guard = ttk.Combobox(main_frame, values=DEFAULT_SCAN_STATUS_OPTIONS, width=36, font=("Arial", input_font_size), state="readonly") # Match width of entry widgets
combo_ip_guard.grid(row=11, column=1, sticky="ew", pady=5)
combo_ip_guard.config(state=tk.DISABLED)
# --- Row 11: 病毒是否扫描 ---
tk.Label(main_frame, text="病毒扫描:", font=("Arial", label_font_size)).grid(row=12, column=0, sticky="w", pady=5)
combo_ntivirus_scan = ttk.Combobox(main_frame, values=DEFAULT_SCAN_STATUS_OPTIONS, width=36, font=("Arial", input_font_size), state="readonly")
combo_ntivirus_scan.grid(row=12, column=1, sticky="ew", pady=5)
combo_ntivirus_scan.config(state=tk.DISABLED)
# --- Row 12: 防毒软件是否安装 ---
tk.Label(main_frame, text="防毒软件:", font=("Arial", label_font_size)).grid(row=13, column=0, sticky="w", pady=5)
combo_antivirus_installed = ttk.Combobox(main_frame, values=DEFAULT_INSTALLED_STATUS_OPTIONS, width=36, font=("Arial", input_font_size), state="readonly")
combo_antivirus_installed.grid(row=13, column=1, sticky="ew", pady=5)
combo_antivirus_installed.config(state=tk.DISABLED)
# --- Row 13: USB 是否禁用 ---
tk.Label(main_frame, text="USB 禁用:", font=("Arial", label_font_size)).grid(row=14, column=0, sticky="w", pady=5)
combo_usb_disabled = ttk.Combobox(main_frame, values=DEFAULT_USB_STATUS_OPTIONS, width=36, font=("Arial", input_font_size), state="readonly")
combo_usb_disabled.grid(row=14, column=1, sticky="ew", pady=5)
combo_usb_disabled.config(state=tk.DISABLED)
# --- Row 14: 防火墙是否启用 ---
tk.Label(main_frame, text="防火墙是否启用:", font=("Arial", label_font_size)).grid(row=15, column=0, sticky="w", pady=5)
combo_firewall_enabled = ttk.Combobox(main_frame, values=DEFAULT_FIREWALL_STATUS_OPTIONS, width=36, font=("Arial", input_font_size), state="readonly")
combo_firewall_enabled.grid(row=15, column=1, sticky="ew", pady=5)
combo_firewall_enabled.config(state=tk.DISABLED)

# --- 提交按钮 ---
# 使用ttk.Button以获得更好的平台原生外观
submit_button = ttk.Button(main_frame, text="提 交", command=submit_data) # 减少了 width/height, 让它更灵活
submit_button.grid(row=16, column=0, columnspan=2, pady=20) # 增加了 pady

# --- 窗口尺寸和居中 ---
# 自动调整窗口大小以适应内容,然后居中
root.update_idletasks() # 必须在获取尺寸前调用
root.geometry("") # 允许 Tkinter 自动调整大小
center_window(root)


# --- 启动时填充自动字段 ---
populate_auto_fields()

# --- 运行主事件循环 ---
root.mainloop()


普通分类: