使用选定的列表框项打开一个新窗口(Python)

时间:2015-01-27 08:53:08

标签: python listbox tkinter

我刚开始使用tkinter进行编码,而且有点卡住了。 我的目标是创建一个带有列表的第一个窗口。用户从列表中选择一个项目。根据所选项目的不同,会弹出一个新窗口,用户可以在其中输入剩余程序的内容。 我的想法是创建一个if:  如果有选择=== firstitem:             弹出新窗口

我曾尝试阅读(很多)类似的主题,但我似乎无法真正理解我做错了什么。

import tkinter 

class simpleapp_tk(tkinter.Tk):
    def __init__(self,parent):
        tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()     

def initialize(self):            
    self.grid()

  self.labelVariable = tkinter.StringVar()
    label = tkinter.Label(self,textvariable=self.labelVariable,
                       font=('courier',10,'bold'),anchor="w",fg="red",bg="white")
    label.grid(column=0,row=1,columnspan=2,sticky='EW')
    self.labelVariable.set(u"Modélisation de populations atteintes d'un virus")

    v=tkinter.Listbox(self)
    v.insert("end","Modèle SIR")
    v.insert("end", "Modèle de Witowski")
    v.insert("end", "Modèle de Munz")
    v.insert("end", "Modèle avec infection latente")
    v.insert("end", "Modèle avec traitement")
    v.bind("<Double-Button-1>", self.OnDouble)
    v.grid(row=2,column=0)

    self.grid_columnconfigure(0,weight=1)


def Double(self, event):

    widget = event.widget
    selection=widget.curselection()
    value = widget.get(selection[0])
    print(value)
    return(selection)
  

这是它不起作用的地方

lisi=Double(self, event)
if lisi==(0,):
    print(1)

if __name__ == "__main__":
app = simpleapp_tk(None)
app.title('Projet informatique')
app.mainloop()

感谢您提供任何帮助!

2 个答案:

答案 0 :(得分:1)

绑定到事件的函数不应该返回任何内容,因为没有地方可以返回数据。没有功能等待结果。到用户点击时,程序的主要逻辑就会完成,mainloop将会运行。

代码示例的最后一部分没有任何意义。您通常不会直接调用绑定函数。相反,您等待用户调用事件(即:双击窗口小部件)。

答案 1 :(得分:-1)

Tkinter一见钟情并不容易,但经过一些错误确实很有用。我很确定你会在某些日子里同意我的意见;) 我改变了你的脚本。我认为你不需要在你的内部继承Tkinter的类。你可以看到我没有。也许这不是你所需要的,但我认为这可能是一个很好的起点。你可以注意到我用pack改变了网格布局:如果你玩它有点比网格布局更灵活,可以提供更好的用户体验。顺便说一下,我在儿童窗口内使用了网格布局,这样你就可以在那里查看是否有问题。 我希望这可以帮到你。

from tkinter import *

class GUI:
    def __init__(self):
        self.root      = Tk()
        self.labelVariable = StringVar()
        self.root.title('Projet informatique')
        self.initialize()
        self.root.mainloop()

    def initialize(self):
        #You don't need to let your class be an instance of Tkinter class. 
        #Therefore you doesn't need self.grid() call.
        #Just create a main frame from "self.root" (Tk instance) and put widgets
        #inside the frame. You could also need to create several frame,
        #for more complex layouts, but this doesn't seems the case...
        #Main frame(used to contain widgets):
        self.main = Frame(self.root)
        #In this window i used "pack" manager just to show you a quicker way to 
        #accomplish your task, but it's just an example.
        self.main.pack() 

        label = Label(self.main, textvariable=self.labelVariable, font=('courier',10,'bold'), anchor="w", fg="red", bg="white")
        label.pack()

        self.labelVariable.set(u"Modélisation de populations atteintes d'un virus")

        v=Listbox(self.main)
        v.insert("end","Modèle SIR")
        v.insert("end", "Modèle de Witowski")
        v.insert("end", "Modèle de Munz")
        v.insert("end", "Modèle avec infection latente")
        v.insert("end", "Modèle avec traitement")
        v.bind("<Double-Button-1>", self.Double) #your method call must match. In this case i drop "On" and it works.
        #v.grid(row=2,column=0) #your old code to layout widget
        v.pack(expand=1,fill=BOTH) #another way to layout widgets

        #self.grid_columnconfigure(0,weight=1)

    def Double(self,event):
        widget    = event.widget
        selection = widget.curselection()
        value     = widget.get(selection[0])
        self.newWindow(value)
        #Your function doesn't need to return anything (if i understood what you meant!)
        #return(selection)

    def ModifyTextarea(self,elem,msg,clear=None):
        """This function let you modify a text widget easier. It's just an helper function"""
        elem.config(state=NORMAL)
        if clear:
            elem.delete(1.0, END)
        else:
            elem.insert(END,msg)
        elem.config(state=DISABLED)

    def newWindow(self,msg):
        """This is the function you asked for. It creates a new window clicking on main window items. I layout it with grid layout as you can see"""
        top = Toplevel(self.root)
        q1 = Frame(top)
        q1.pack()
        top.grab_set()

        scrollbar = Scrollbar(q1)
        scrollbar.grid(row=0,column=3,sticky=NS)
        text = Text(q1,relief=FLAT,yscrollcommand=scrollbar.set,state=DISABLED,exportselection=True)
        text.grid(row=0,column=0,columnspan=3)

        lbl = Label(q1,text="")
        lbl.grid(row=1,column=0,columnspan=3)

        self.ModifyTextarea(text,msg)

        scrollbar.configure(command=text.yview)

        btnquit = Button(q1,borderwidth = 1,text = "Ok",command = lambda: top.destroy())
        btnquit.grid(row=2,column=1,sticky=W+E)

if __name__ == "__main__":
    """I put all tkinter logic inside GUI class in this way you only need to instantiate it, but if you prefer, you can add an additional method "show", it's up to you. This is just an example"""
    app = GUI()