2015-10-05 111 views
1

我目前正在一个类中使用Tkinter的GUI。我希望GUI根据以前的选择向用户询问各种输入。另外,我会注意到我对python比较陌生,绝对是Tkinter。不过,我之前已经在MATLAB中制作了GUI。Tkinter事件小部件

所以,我想要做的是以下几点:

  1. 要求用户提供速度来处理,用逗号分隔。然后用户将输入如下所示的速度:[90,100,102p5]。
    • 要从条目中获得输入,您必须按Enter键,该键将调用函数以获取速度字符串。然后我输入输入的字符串并根据逗号分隔它们以形成一个列表。
  2. 然后,一旦输入速度,我想更新GUI并显示每个速度的输入部分,以逗号分隔的特定速度输入各种压力。压力将以[100kpa,200kpa,300kpa,400kpa]的形式出现。
    • 要获得为每个压力输入的值,必须在每个输入框中按enter键,就像之前一样。我再次将这个字符串形成一个压力列表。

,我有工作的方法,但是我不认为这是最好的做法。这是查看输入各种速度时GUI的外观的链接,如步骤1中所述:GUI Image

最终,在此GUI的最后,我希望有一个速度列表,并且对于每个速度a压力清单。然后,我将采取这些列表,并让他们到另一个功能来运行我以前创建的程序。

有一点需要注意的是,我不知道用户需要处理多少速度。我也不知道每种速度会输入多少压力。

所以,这些是我的问题: 这是用Tkinter处理事件的“pythonic”方式吗?我没有在网上找到任何关于如何根据上一个完成(通过按Enter键)显示一个新小部件的任何信息。

我也不是100%确定在不同方法之间传递变量的最佳方法是通过使变量成为自身属性。例如,我如何传递“speeds”变量和字典“bp”。我应该使用全局变量吗?它也变得复杂,因为我必须通过一个事件来传递变量,这个事件不允许额外的参数。

非常感谢您的帮助!如果你知道一个很好的网站,以更有用的方式解释Tkinter,那也会有帮助!

from Tkinter import * 
import tkMessageBox 


class MyWindow(Frame): 
    def __init__(self, master): 
      self.speeds = [] 
      Frame.__init__(self, master) 
      self.speed_widgets() 

    def speed_widgets(self): 
      label = Label(self.master, text="Enter the speeds you want to process, seperated by a comma:") 
      label = label.grid(row=0) 
      self.speeds_text = Entry(self.master) 
      self.speeds_text.grid(row=0, column=1) 
      self.speeds_text.bind('<Return>', self.get_speeds) 


    def get_speeds(self, event): 
      #global speeds 
      self.speeds = self.speeds_text.get() 
      if (not self.speeds): 
        tkMessageBox.showerror('Invalid Entry','Please enter at least one speed.') 
      else: 
        self.speeds = ''.join(self.speeds.split()) 
        self.speeds = self.speeds.split(',') 
        num_speeds = len(self.speeds) 
        #print speeds 
      self.bp_widget() 


    def bp_widget(self): 
      keys = [] 
      for speed in self.speeds: 
        keys.append(speed) 
      self.bp = dict.fromkeys(keys) 

      label = Label(self.master, text='Enter the back pressures for each speed, seperated by a comma:') 
      label = label.grid(row=1) 

      i = 2 
      self.bp_text_widgets = [] 
      for speed in self.speeds: 
        label = Label(self.master, text=speed+'=') 
        label.grid(row=i, column=0) 

        self.bp_text_widgets.append(Entry(self.master)) 
        self.bp_text_widgets[i-2].grid(row=i,column=1) 
        self.bp_text_widgets[i-2].bind('<Return>', lambda event, arg=i: self.get_bp(event, arg)) 
        i += 1 

    def get_bp(self, event, i): 
      self.bp[self.speeds[i-2]] = self.bp_text_widgets[i-2].get() 
      print self.bp[self.speeds[i-2]] 


root = Tk() 
MyWindow(root) 
root.mainloop() 
+0

tkinter的一个很棒的网站:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html – saulspatz

+0

'self.speed_widgets()def speed_widgets(self):'是一行语法错误。请发布工作代码,或者至少需要编译的代码。 – saulspatz

+0

谢谢你的链接!对于格式问题感到抱歉 - 当我将代码从vi复制到本网站时必定发生。我确实修复了它。 – elmons13

回答

0

关于全局变量的问题很容易回答。一般来说,最好避免它们。从我看到的情况来看,将价值保存为属性是绝大多数人会这样做的方式。

至于你对输入小部件做了什么,我看到了一些问题。首先,如果我在第一个窗口小部件中输入五个速度,然后按Enter,则会出现五个新的窗口小部件。到现在为止还挺好。但是,如果我现在意识到我犯了一个错误并返回并删除速度,我仍然有5个输入小部件。我玩过这个,添加和删除速度,我可以将GUI全部弄乱。

其次,如果我在添加背压后忘记按Enter键,或者如果我在背压中纠正了一个错误,然后忘记按下Enter,会发生什么?问题是我只看到输入,并且没有确认应用程序实际收到的内容。

这可能是一种品味问题,但我喜欢做的是在可能的情况下弹出一个用于输入数据的对话框并在GUI中的某处回显输入数据。所以,我会有一个标有“输入速度”的按钮,弹出一个对话框,让用户输入速度。当他点击确定后,将会创建一个标签,其中包含文字“速度70 80 90”。标签旁边会出现一个“编辑”按钮,以防使用改变主意或想要输入新问题。

对于每个速度,我会弹出一个对话框,其中包含如下指令:“输入速度80的压力”。当用户单击确定时,标签将显示相关数据和编辑按钮。

如果我理解你是正确的,未使用的条目坚持的原因是你不知道如何让它们消失。查找grid_forget方法。例如:

http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-methods.html

我希望我已经解决您的问题。让我知道我是否错过了一些东西。

编辑:至于什么是做“控制流”的“最佳方式”,当然,我没有答案。就我个人而言,我喜欢让方法做一件事并返回。我将有另一个函数负责以正确的顺序调用数据输入方法。这样,数据输入方法是可分离的。如果用户意识到他忘记了某些东西,并且想要返回,我可以独立地给他们打电话。这可能与您的设置也可能,但交互不是很清楚。毫无疑问,这主要是我习惯的问题。尽管如此,我发现尽可能使事情彼此独立,简化未来的变革。另外,我不知道GUI还有多少。如果你所展示的几乎是所有的用户交互,那么我认为你所拥有的将会很好地工作。

+0

非常感谢您的回复。我仍然有一个问题。我称之为一种方法,然后在第一种方法结束时调用另一种方法,即“最佳”方法来做我想做的事情?例如,我调用“speed_widgets”,然后调用“get_speeds”,然后根据最后一个方法的输入调用“bp_widgets”?当我在MATLAB中制作图形用户界面时,我记得我可以通过输入由程序员定义的特定信息来激活先前停用的其他窗口小部件。我确实喜欢弹出窗口的想法,而grid_forget方法很有帮助。再次感谢你! – elmons13

+0

我编辑了我的答案,给你我的想法。这主要是个人意见。我已经习惯了似乎适合我的习惯,但其他人可能不喜欢我的控制流程的工作方式。如果你的图形用户界面能够做到你想要的,并且它能够正常工作,那么我不会过分担心它是否是“pythonic”。无论如何,这个词似乎并不太重要。或者至少,这似乎意味着每个使用它的人都会有所不同。 – saulspatz