10

或者也许是懒惰的方式..

我正在寻找一个 python 模块,它具有一些内置的 GUI 方法来获得快速的用户输入——一个非常常见的编程案例。必须在 Windows 7 上工作

我的理想案例

import magicGUImodule
listOfOptions = ["option 1", "option 2", "option 3"]
choosenOptions = magicGUImodule.getChecklist(listOfOptions, 
                            selectMultiple=True, cancelButton=True)

这有点像raw_input,但有一个 GUI。因为这是一个常见的编程任务,所以肯定有一些东西。


更新

@alecxe,我未选中您的答案作为我问题的解决方案,这并不失礼。我仍然希望能够在我正在处理的任何脚本中使用我的理想案例,而您的回答让我成功了一半。

我以为我可以轻松地将@alecxe 的解决方案实现到一个模块中,但这并不是那么简单(对我来说)..

到目前为止,这是我的模块:

# This serve as a module to get user input - the easy way!
# Some GUI selection
#from Tkinter import *
import Tkinter

master = Tkinter.Tk()
input = None
listbox = None

def chooseFromList(list, windowTitle="Choose from list", buttonText="Submit", selectMultiple=False, w=150, h=30):
    global listbox
    listbox = Tkinter.Listbox(master, selectmode=MULTIPLE if selectMultiple else SINGLE, width=w, height=h)
    listbox.master.title(windowTitle)
    for option in list:
        listbox.insert(0, option)
    listbox.pack()
    #listbox.selection_set(1)
    b = Tkinter.Button(master, command=callback(listbox), text=buttonText)
    b.pack()
    mainloop()

def callback(listbox):
    global listbox
    setInput(listbox.selection_get())
    master.destroy()    

def setInput(var):
    global input
    input = var

def getInput():
    global input
    return input

这是我的脚本

import GetUserInput
listOfOptions = ["option 1", "option 2", "option 3"]
choice = GetUserInput.chooseFromList(listOfOptions)
print choice.getInput()

但我只是得到错误

can't invoke "listbox" command: application has been destroyed

尝试了很多不同的选项,我虽然可以解决这个问题(比如使用全局变量) - 但没有任何运气。

更新 2

@blablatros 为我提供了我正在寻找的解决方案。

4

7 回答 7

13

Easygui模块正是您所需要的:

import easygui as eg

question = "This is your question"
title = "This is your window title"
listOfOptions = ["option 1", "option 2", "option 3"]

choice = eg.multchoicebox(question , title, listOfOptions)

choice将返回选定答案的列表。

用于multchoicebox选择题或choicebox单选题。

于 2013-06-26T20:46:18.433 回答
7

这是一个使用的简单示例(而不是使用多选Tkinter复选框):listbox

from Tkinter import *


def callback():
    print listbox.selection_get()
    master.destroy()


master = Tk()

listbox = Listbox(master, selectmode=MULTIPLE)
for option in ["option 1", "option 2", "option 3"]:
    listbox.insert(0, option)
listbox.pack()

b = Button(master, command=callback, text="Submit")
b.pack()

mainloop()

更新:

GetUserInput.py

from Tkinter import *


class GetUserInput(object):
    selection = None

    def __init__(self, options, multiple):
        self.master = Tk()

        self.master.title("Choose from list")

        self.listbox = Listbox(self.master, selectmode=MULTIPLE if multiple else SINGLE, width=150, height=30)
        for option in options:
            self.listbox.insert(0, option)
        self.listbox.pack()

        b = Button(self.master, command=self.callback, text="Submit")
        b.pack()

        self.master.mainloop()

    def callback(self):
        self.selection = self.listbox.selection_get()
        self.master.destroy()

    def getInput(self):
        return self.selection

主脚本:

from GetUserInput import GetUserInput

listOfOptions = ["option 1", "option 2", "option 3"]
print GetUserInput(listOfOptions, True).getInput()

希望有帮助。

于 2013-06-19T08:30:53.903 回答
4

我已经迭代了@alecxe 的答案,使用 OOP 以更强大的方式管理 GUI 生命周期:

图形用户界面元素

# This serve as a module to get user input - the easy way!
# Some GUI selection
import Tkinter

default_kwargs = { 
                  'selectmode'  : "single"          ,
                  'width'       : "150"             ,
                  'height'      : "30"              ,
                  'title'       : "Choose from list",
                  'buttonText'  : "Submit"  
}



class easyListBox:

    def __init__(self, options_list, **kwargs) :

        #options
        opt = default_kwargs #default options
        opt.update(kwargs) #overrides default if existant

        #Return value
        self.selected = 0;

        # GUI master object (life-time component)
        self.master = Tkinter.Tk()

        # Checklist with options
        listbox_options = { key: opt[key] for key in opt if key in['selectmode','width','height'] } #options slice for GUI
        self.listbox = Tkinter.Listbox(self.master, listbox_options)
        self.listbox.master.title(opt['title'])

        #Options to be checked
        for option in options_list:
            self.listbox.insert(0,option)
        self.listbox.pack()

        # Submit callback
        self.OKbutton = Tkinter.Button(self.master, command=self.OKaction, text=opt['buttonText'] )
        self.OKbutton.pack()

        #Main loop
        self.master.mainloop()

    # Action to be done when the user press submit
    def OKaction(self):
        self.selected =  self.listbox.selection_get()
        self.master.destroy() 

    # Return the selection
    def getInput(self):
        return self.selected

父脚本

#import GetUserInput
import GUI as GetUserInput

listOfOptions = ["option 1", "option 2", "option 3"]
GUI_options = {'title' : "Custom title", 'selectmode' : 'multiple' }
#choice = GetUserInput.chooseFromList(listOfOptions)
elb = GetUserInput.easyListBox(listOfOptions, **GUI_options)
print elb.getInput()

我添加了一些默认参数 kwargs 以处理可变参数。

PS:我使用的是 Python 2.7,所以必须调整一些值(例如 MULTIPLE -> 'multiple')

于 2013-06-24T08:29:25.203 回答
3

列表框

import Tkinter

def callback(master, listbox, selection):
    selection[:] = [listbox.get(i) for i in map(int, listbox.curselection())]
    master.destroy()

def chooseFromList(options, windowTitle="Choose from list", buttonText="Submit", selectMultiple=False, w=150, h=30):
    master = Tkinter.Tk()
    master.title(windowTitle)
    listbox = Tkinter.Listbox(master, selectmode=Tkinter.MULTIPLE if selectMultiple else Tkinter.SINGLE, width=w, height=h)
    for option in options:
        listbox.insert(Tkinter.END, option)
    listbox.pack()
    selection = []
    Tkinter.Button(master, command=lambda: callback(master, listbox, selection), text=buttonText).pack()
    master.mainloop()
    return selection

复选按钮 + 单选按钮

对多个选项使用 Checkbutton,对单个选项使用 Radiobutton。

def chooseFromList(options, windowTitle="Choose from list", buttonText="Submit", selectMultiple=False, w=150, h=30):
    master = Tkinter.Tk()
    master.title(windowTitle)

    variables = []
    if selectMultiple:
        for option in options:
            v = Tkinter.StringVar()
            variables.append(v)
            Tkinter.Checkbutton(text=option, variable=v, onvalue=option, offvalue='').pack()
    else:
        v = Tkinter.StringVar()
        variables.append(v)
        for option in options:
            Tkinter.Radiobutton(text=option, variable=v, value=option).pack()

    Tkinter.Button(master, command=master.destroy, text=buttonText).pack()
    master.mainloop()
    return [v.get() for v in variables if v.get()]
于 2013-06-24T08:23:37.960 回答
1

好吧,你不会那么得到一些东西,几乎不管你在哪里看,我不认为。通常,您至少需要足够的样板来创建顶级窗口和/或小部件来布局您真正关心的输入小部件。

Python 对 GTK2 和 Qt(PyQt,目前使用 4.X)都有很好的绑定,这两种工具包都是非常高质量的跨平台 GUI 工具包,很容易上手。还有其他的,wxWidgets 是另一个突出的,但其余的(包括内置的 IMO)已经过时了。

于 2013-06-19T08:07:20.187 回答
1

Tkinter是在 Python 中构建的,具有您上面所说的形式的复选框,并且比大多数其他 GUI 模块更简单。请在这里找到一个好的教程(虽然需要一些刷新)。官方文档在这里

于 2013-06-19T08:26:44.853 回答
1

从这里你可能会得到准确的答案。只需点击这里http://www.blog.pythonlibrary.org/2013/02/27/wxpython-adding-checkboxes-to-objectlistview/

于 2013-06-30T12:58:35.057 回答