2017-05-09 69 views
1

我有一个Excel电子表格,我正在从中提取信息。这可能会在某个时候变成数据库,但现在可以用于测试。它与数据两列,看起来像:从字典列表中选择Python Tkinter单选按钮

Key | ProgramName |  Path 

0  | Calculator  |  C:\Windows\System32\calc.exe 
1  | Notepad  |  C:\Windows\System32\notepad.exe 

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

这给我的字典项的列表:

[{'Path':'C:\Windows\System32\notepad.exe', 'Program':'Notepad', 'Key':0.0}, {'Path':'C:\Windows\System32\calc.exe', 'Program':'Calculator', 'Key':1.0}] 

我可以得到单选按钮体面的工作,但我有一个问题,拉路径数据,并重新使用它,因为我将(希望)使用subprocess.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按钮时,正确的路径被拉到这样我就可以把它变成一个“subprocess.Popen”命令。 我是否需要创建另一个变量?我可以使用字典键来获取这些信息吗?

任何建议,非常感谢。

+0

检查您的格式。它看起来像'programRun'应该缩进。 –

回答

1

从示例中拉出路径并不是一件难事,这里甚至有两个选项可供选择。而且你不需要创建另一个变量。

根据Docs

可变选项必须被设置为控制变量,无论是一个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:\Windows\System32\notepad.exe', 'Program': 'Notepad', 'Key': 0.0}, 
          {'Path': r'C:\Windows\System32\calc.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() 
+0

TY的帮助!感谢这样一个解释良好的答复! – Shiroslullaby