字典列表中的 Python Tkinter 单选按钮



我有一个 Excel 电子表格,我正在从中提取信息。这可能会在某个时候更改为数据库,但现在可以进行测试。它有两列包含数据,如下所示:

Key    |    ProgramName    |     Path
0      |    Calculator     |     C:WindowsSystem32calc.exe
1      |    Notepad        |     C:WindowsSystem32notepad.exe 

我使用 Python Tkinter 构建了一个非常基本的 GUI,并使用 xlrd 库将数据从电子表格中提取到包含字典条目的列表中。
https://pypi.python.org/pypi/xlrd

这给了我一个包含字典条目的列表:

[{'Path':'C:WindowsSystem32notepad.exe', 'Program':'Notepad', 'Key':0.0}, {'Path':'C:WindowsSystem32calc.exe', 'Program':'Calculator', 'Key':1.0}]

我可以让单选按钮正常工作,但我在拉取路径数据并重复使用它时遇到了问题,因为我(希望)使用子流程。Popen 以实际打开所选程序。

这是到目前为止的代码:

from Tkinter import *
from xlrd import open_workbook
import os
import subprocess
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
bottomframe= Frame(master)
bottomframe.pack(side = BOTTOM)
book = open_workbook('programlist.xls')
sheet = book.sheet_by_index(0)
# read header values into the list    
keys = [sheet.cell(0, col_index).value for col_index in xrange(sheet.ncols)]
global dict_list
dict_list = []
for row_index in xrange(1, sheet.nrows):
d = {keys[col_index]: sheet.cell(row_index, col_index).value 
for col_index in xrange(sheet.ncols)}
dict_list.append(d)
self.w = StringVar()
self.w.set(dict_list[0]['Key']) # initialize
for eachprogram in dict_list:
self.c = Radiobutton(master, text=eachprogram['Program'], variable=self.w, value=eachprogram['Key'])
self.c.pack(anchor=W)

self.quitButton = Button(
bottomframe, text="QUIT" , fg="red", command=frame.quit
)
self.quitButton.pack(side=LEFT, anchor=S)

self.programRun = Button(bottomframe, text="Run", command=self.programRun)
self.programRun.pack(side=LEFT, anchor=S)

def programRun(self):
???
root = Tk()
app = App(root)
root.mainloop()
root.destroy()

不确定我需要做什么,以便在按下 programRun 按钮时,会拉出正确的路径,以便我可以将其放入"子进程"。波彭"命令。 我需要创建另一个变量吗?我可以使用字典键提取此信息吗?

任何建议将不胜感激。

从您的示例中拉出路径并不是一项艰巨的任务,这里甚至有两个选项可供选择。而且您不需要创建另一个变量。

根据文档:

变量选项必须设置为控制变量,即 IntVar 或 StringVar。功能组中的所有单选按钮必须共享相同的控制变量。

将组中每个单选按钮的值选项设置为不同的值。每当用户设置单选按钮时,变量都将设置为该单选按钮的值选项,并且共享该组的所有其他单选按钮将被清除。

如您所见 - 您不需要使用StringVar,但DoubleVar,因为您的value参数(和键)floats。这里的缺点 - 您需要遍历列表以检查每个字典的Key

try:
import tkinter as tk
except ImportError:
import Tkinter as tk

class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.frame = tk.Frame(self)
self.frame.pack()
self.bottomframe = tk.Frame(self)
self.bottomframe.pack(side=tk.BOTTOM)
# book = open_workbook('programlist.xls')
# sheet = book.sheet_by_index(0)
# read header values into the list
# keys = [sheet.cell(0, col_index).value for col_index in xrange(sheet.ncols)]
self.keys = ['Key', 'ProgramName', 'Path']
self.dict_list = [{'Path': r'C:WindowsSystem32notepad.exe', 'Program': 'Notepad', 'Key': 0.0},
{'Path': r'C:WindowsSystem32calc.exe', 'Program': 'Calculator', 'Key': 1.0}]
# global dict_list
# dict_list = []
# for row_index in xrange(1, sheet.nrows):
#    d = {keys[col_index]: sheet.cell(row_index, col_index).value
#       for col_index in xrange(sheet.ncols)}
#    dict_list.append(d)
self.w = tk.DoubleVar()
self.w.set(self.dict_list[0]['Key'])  # initialize
for each_program in self.dict_list:
self.c = tk.Radiobutton(self.master, text=each_program['Program'], variable=self.w, value=each_program['Key'])
self.c.pack(anchor=tk.W)

self.quitButton = tk.Button(
self.bottomframe, text="QUIT", fg="red", command=self.frame.quit
)
self.quitButton.pack(side=tk.LEFT, anchor=tk.S)

self.programRun = tk.Button(self.bottomframe, text="Run", command=self.programRun)
self.programRun.pack(side=tk.LEFT, anchor=tk.S)
def programRun(self):
print('Pulled path: %s' % self.search_list_dict())
def search_list_dict(self):
try:
return [item for item in self.dict_list if item['Key'] == self.w.get()][0]['Path']
except IndexError:
return ''
app = App()
app.mainloop()

作为替代方案 - 您可以使用StringVarPath项作为value参数!只需更改一些行:

try:
import tkinter as tk
except ImportError:
import Tkinter as tk

class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
...
self.w = tk.StringVar()
self.w.set(self.dict_list[0]['Path'])  # initialize
for each_program in self.dict_list:
self.c = tk.Radiobutton(self.master, text=each_program['Program'], variable=self.w, value=each_program['Path'])
self.c.pack(anchor=tk.W)
...
def programRun(self):
print('Pulled path: %s' % self.w.get())
app = App()
app.mainloop()

最新更新