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

时间:2017-05-09 22:56:51

标签: python dictionary tkinter

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

Key    |    ProgramName    |     Path

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

我使用Python Tkinter构建了一个非常基本的GUI,并使用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”命令中。 我需要创建另一个变量吗?我可以使用字典键来提取此信息吗?

非常感谢任何建议。

1 个答案:

答案 0 :(得分:1)

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

根据Docs

  

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

     

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

如您所见 - 您不需要使用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()