手机端Python Roku控制脚本:变量内存存储优化方案问询
问题描述
我在手机上编写了一款控制Roku电视的Python脚本,运行效果良好,但使用标准方法查找网络中的Roku设备时,仅会返回第一个响应的设备。为此我添加了「存储」和「调用」按钮,以便在网络设备间循环切换(已添加逻辑:仅当找到的设备未被存储时才显示「存储」按钮;「调用」按钮可切换至存储列表中当前设备的下一个设备)。目前该功能可正常运行,但由于Tkinter的背景画布与按钮处于循环中,全局变量会持续重置,因此我只能通过文件来存储和读取变量。通常我会将变量传递至第二个(内存)脚本,并在每次事件触发时读取,但手机一次仅能运行一个脚本。请问是否有更优的方式在内存中保存变量(主要为当前设备信息)?
当前代码片段
#!/usr/bin/env python #Imports come first then #defs read the file to a variable #After defs I find the first Roku device to respond #I'm writing that as a variable to a file Store_Location = open('/storage/emulated/0/Movies/Roku/MMemory.ini', 'w') Store_Location.write(location) Store_Location.close() #It works #Then Tkinter and buttons are standard and work then after buttons I root.mainloop()
解决方案
你完全不需要依赖文件存储,以下几种内存内的方案更高效:
1. 用自定义类管理设备状态
创建一个专门的类来存储设备列表和当前选中的索引,这个类的实例会在Tkinter主循环全程存活,不会被重置。
示例代码:
import tkinter as tk class RokuDeviceManager: def __init__(self): self.devices = [] # 存储所有已保存的Roku设备地址 self.current_idx = 0 # 当前选中的设备索引 # 初始化管理器,在主循环前创建,全程有效 device_manager = RokuDeviceManager() # 找到第一个设备后,先加入管理器 location = "你的第一个设备地址" # 替换成实际获取到的设备地址 if location not in device_manager.devices: device_manager.devices.append(location) # 存储按钮的回调函数 def handle_store(): if location not in device_manager.devices: device_manager.devices.append(location) # 可选:更新UI,比如隐藏存储按钮 store_btn.config(state=tk.DISABLED) # 调用按钮的回调函数 def handle_next(): if len(device_manager.devices) <= 1: return # 只有一个设备时无需切换 # 循环切换到下一个设备 device_manager.current_idx = (device_manager.current_idx + 1) % len(device_manager.devices) current_device = device_manager.devices[device_manager.current_idx] # 这里可以加入更新UI或切换控制目标的逻辑 print(f"当前切换到设备:{current_device}") # 初始化Tkinter界面 root = tk.Tk() store_btn = tk.Button(root, text="存储", command=handle_store) next_btn = tk.Button(root, text="调用", command=handle_next) # 根据设备是否已存在设置按钮状态 if location in device_manager.devices: store_btn.config(state=tk.DISABLED) store_btn.pack() next_btn.pack() root.mainloop()
2. 使用全局变量(简化版)
只要全局变量在Tkinter主循环之前初始化,就不会被重置。在回调函数里用global关键字声明即可修改全局变量:
import tkinter as tk # 全局变量,在主循环前定义 roku_devices = [] current_idx = 0 # 找到第一个设备后加入列表 location = "你的第一个设备地址" if location not in roku_devices: roku_devices.append(location) def handle_store(): global roku_devices if location not in roku_devices: roku_devices.append(location) store_btn.config(state=tk.DISABLED) def handle_next(): global current_idx, roku_devices if len(roku_devices) <= 1: return current_idx = (current_idx + 1) % len(roku_devices) print(f"当前设备:{roku_devices[current_idx]}") root = tk.Tk() store_btn = tk.Button(root, text="存储", command=handle_store) next_btn = tk.Button(root, text="调用", command=handle_next) if location in roku_devices: store_btn.config(state=tk.DISABLED) store_btn.pack() next_btn.pack() root.mainloop()
3. 用闭包封装状态
如果不想用类或全局变量,可以用闭包把设备状态封装在函数内部,回调函数可以直接访问闭包内的变量:
import tkinter as tk def create_device_manager(): devices = [] current_idx = 0 def store(location): nonlocal devices if location not in devices: devices.append(location) def next_device(): nonlocal current_idx, devices if len(devices) <= 1: return None current_idx = (current_idx + 1) % len(devices) return devices[current_idx] def get_devices(): return devices return store, next_device, get_devices # 初始化闭包管理器 store_device, next_device, get_devices = create_device_manager() # 添加第一个设备 location = "你的第一个设备地址" store_device(location) def handle_store(): store_device(location) store_btn.config(state=tk.DISABLED) def handle_next(): device = next_device() if device: print(f"当前切换到:{device}") root = tk.Tk() store_btn = tk.Button(root, text="存储", command=handle_store) next_btn = tk.Button(root, text="调用", command=handle_next) if location in get_devices(): store_btn.config(state=tk.DISABLED) store_btn.pack() next_btn.pack() root.mainloop()
这三种方案都能在内存中持久保存设备状态,无需读写文件,比你的当前方案更高效且响应更快。
内容的提问来源于stack exchange,提问作者Kogije Boss Rabbit
相关产品推荐
相关产品推荐

