如何使用Tk文本框选择和绘制不同的数据集?

时间:2014-11-03 01:01:12

标签: python graph tkinter

我是一个Python 2.7 / Tk新手试图创建一个gui来显示来自不同数据文件的图形。下面的骨架程序使用Entry小部件来取名字" data1"和" data2"。默认情况下,将显示data1的图形。我希望当一个人输入" data2"时,图表会更改为data2。并按回车。

我尝试过这样做,有没有课,没有运气。

我也试过使用Button,但也没有成功。

为什么dataname = etr.get()不起作用?

import sys
if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk
from Tkinter import Label, Entry, Button, TOP, LEFT, BOTH #, Canvas, Frame, W, N, E, S

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

import numpy as np

def plot_data(fig, dat_name):
    t = np.arange(10)
    v1 = [1,2,3,4,5,4,4,4,4,4]
    v2 = [4,4,4,4,5,4,4,3,2,1]
    if dat_name[4] == 2:
        y = v2
    else:
        y = v1
    a = fig.add_subplot(111)
    a.plot(t,y, color='red')
    a.set_title('Graph of ')    
    a.set_xlabel('time (s)')
    a.set_ylabel('voltage (mv)')

root = tk.Tk()
root.geometry("500x250+200+200")
dataname = 'data1'

f = Figure(figsize=(4,3), dpi=72)
canvas = FigureCanvasTkAgg(f, master=root)
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

#plot_data(f, dataname)

lbl = Label(root, text='Current data:  ')
lbl.pack(side=LEFT)

etr = Entry(root, width=20)
etr.pack(side=LEFT)
etr.delete(0, last=None)
etr.insert(0, dataname) # What is the first parameter for???
dataname = etr.get()

#etr_entry.bind("<Return>", entry_handler)
#btn = Button(root, text = 'Open', command=entry_handler)
#btn.pack(side=LEFT)

plot_data(f, dataname)
print('dataname = '+dataname)
root.mainloop()  

2 个答案:

答案 0 :(得分:0)

这是一个有效的解决方案:

import sys
if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk
from Tkinter import Label, Entry, Button, TOP, LEFT, BOTH #, Canvas, Frame, W, N, E, S

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

import numpy as np

class ECG_Dsiplayer(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        master.bind("<c>", lambda x : self.clean())#allow to test the clean function, press "c"
        master.bind("<Return>", lambda x : self.draw_data())

        self.datasetName = tk.StringVar()
        self.datasetName.set("data1") #default value
    # ____________________________________________________  
    def draw_data(self):
        self.clean()
        self._createWidgets()
        self.plot_ecg_data()
    # ____________________________________________________
    def plot_ecg_data(self):
        values = self._load_data(self.datasetName.get())
        a = self.figure.add_subplot(111)
        a.plot(np.arange(len(values)),values, color='red')
        a.set_title('Graph of ')    
        a.set_xlabel('time (s)')
        a.set_ylabel('voltage (mv)')
    # ____________________________________________________
    def _createWidgets(self):
        self.figure = Figure(figsize=(4,3), dpi=72)

        self.canvas = FigureCanvasTkAgg(self.figure, master=self)
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        self.label = Label(self, text='Current data:  ')
        self.label.pack(side=LEFT)

        self.datasetEntry = Entry(self, width=20, textvariable=self.datasetName)
        self.datasetEntry.pack(side=LEFT)
    # ____________________________________________________  
    def _load_data(self, dataName):
        ## TO OVERRIDE IN ORDER TO PROVIDE A TRUE DATA LOADING SYSTEM ##
        if dataName == "data1":
            return [1,2,3,4,5,4,4,4,4,4]
        else:
            return [4,4,4,4,5,4,4,3,2,1]
    # ____________________________________________________  
    def clean(self):
        for widget in self.pack_slaves():
            widget.pack_forget()
    # ____________________________________________________


if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("500x250+200+200")    

    ecg = ECG_Dsiplayer(root)
    ecg.pack(fill=BOTH, expand=1)

    ecg.draw_data()

    root.mainloop()

请注意以下几点:

  • 您的测试用于检查要使用的数据集的哪个位置。它总是返回相同的值,因此您的问题可能来自此行。当您尝试将整数值与字符串1进行比较时,if dat_name[4] == 2:始终为False。
  • 您应该尝试使用更明确的变量名称。我在这里进行了一些重构,但整体代码可读性仍有待提高!
  • 您应该尝试使用网格管理器而不是包。包管理器允许快速构建GUI,但网格管理器可以更好地控制发生的情况。在这里,使用网格管理器将允许仅删除画布小部件并让其他小部件保持不变。它允许在init方法中移动条目和标签代码,永远不会再被调用。如果没有删除包,它们会在第二次调用时进入绘图以绘制数据。

最后,享受python的乐趣,祝你好运!

亚瑟。

答案 1 :(得分:0)

亚瑟,非常感谢你的回答。你提出了许多好的建议。与此同时,我继续工作,制定了一个新的CardioGUI课程。最后,我得到了以下结果:

http://imagizer.imageshack.us/a/img661/3842/zTESMt.png

到目前为止,这是我的代码(显示图表,但仍然有问题)

import numpy as np

from Tkinter import Label, Button, StringVar, LEFT, TOP, BOTH
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

import sys
if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk

def destroy(e): sys.exit()

#root.bind("<Destroy>", destroy)

class CardioGUI:
    LABEL_TEXT = [
        "Example-30s",
        "Example-120s",
        "David-counting",
        "Cynthia-following",
        "Miriam-reading"
     ]
    def __init__(self, master):
        self.master = master
        master.title("Cardiorespiratory GUI")
        self.f = Figure(figsize=(4,3), dpi=72)
#        self.f.set_facecolor('red')

        self.label_index = 0
        self.label_text = StringVar()
        self.label_text.set(self.LABEL_TEXT[self.label_index])
#        plot_data(self.label_text.get())

        self.cvs = FigureCanvasTkAgg(self.f, master=root)
        self.cvs.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.cvs._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        self.lbl1 = Label(master, text='Data') # Non-interactive label
        self.lbl1.pack(side=LEFT)

        self.lbl2 = Label(master, width=30, textvariable=self.label_text)
        self.lbl2.bind("<Button-1>", self.cycle_label_text)
        self.lbl2.pack(side=LEFT)

        self.btn1 = Button(master, text='Plot data')
        self.btn1.bind("<Button-1>", \
          lambda label_text: plot_data(self.label_text.get()))
        self.btn1.pack(side=LEFT)

        self.greet_button = Button(master, text="Analyze", command=self.greet)
        self.greet_button.pack(side=LEFT)

    def greet(self):
        print("Analyse!")

    def cycle_label_text(self, event):
        self.label_index += 1
        self.label_index %= len(self.LABEL_TEXT) # wrap around
        self.label_text.set(self.LABEL_TEXT[self.label_index])
        plot_data(label_text.get())

def plot_data(session_name):
    a = my_gui.f.add_subplot(211)
    b = my_gui.f.add_subplot(212)

    my_gui.cvs.show()

    filepath = 'C:/Users/David/My Documents/Cardiorespiratory Experiment/data/'
    fullfilename = filepath+session_name+'.txt'

    data = np.loadtxt(fullfilename, skiprows=7, usecols=(0,1,2))
    t = [row[0] for row in data]    
    v = [row[1] for row in data]
    p = [row[2] for row in data]

    a.plot(t,v, color='red')
    a.set_title('Heartbeat and Respiration')
    a.set_xlabel('time (s)')
    a.set_ylabel('voltage (mv)')
    b.plot(t,p)
    b.set_xlabel('time (s)')
    b.set_ylabel('pressure (kpa)')
    return # Unclear whether this is needed


root = tk.Tk()
root.geometry("500x250+100+100")
my_gui = CardioGUI(root)
root.mainloop()