2016-12-29 1 views
1

Следуя предложению, которое я получил от Sentdex, я закодировал приложение Python/Tkinter с несколькими страницами, которое, среди прочего, обеспечивает график перемещения по времени на один кадр из множества кадров, которые живут под tk.Tk. Кодирование движущегося графа было немного сложным, поэтому я решил определить холст в классе: GrpCanvas (tk.Canvas).размещение определенного класса объекта tkinter в отдельном кадре, когда многие из них определены с помощью tk.Tk

Моя проблема заключается в том, что эта структура программы, по-видимому, заставляет объект canvas появляться на всех 21 моих страницах! Как я могу управлять кодом, чтобы graphcanvas=GrpCanvas(HomePage) появился только на этой странице? Я прокомментировал некоторые родительские определения, чтобы показать, что я пытался сделать (и не удалось). Я использую Python 3.4.4.

Я показываю код (вырубать столько, сколько я могу, чтобы показать проблему) ниже:

#Avoiding canvas on all pages when pages are managed using tk.Tk 

import tkinter as tk 

sinewave_points=[] #Generated by a sin function of time. 
#class GrpCanvas(self, parent): 
class GrpCanvas(tk.Canvas):  
    #def __init__(self, parent): 
    def __init__(self, parent, controller):  
     tk.Canvas.__init__(self, height=340, width=594, bg='white')#,  x=pos_x, y=pos_y): 
     self.place(x=180, y=80) 

    def set_y_scale(self, sinewave_points): 
     self.scale=100 #actually calculated from a scaling algorithm (adapting to amplitude of sinewave_points) 
     return self.scale 

    def define_graph(self, scale, sinewave_points): 
     # create x-axis 
     self.horizontal=self.create_line(0, 170, 594, 170, width=2) 
     for i in range(13): #used to be 26 
      x = 20 + (i * 48) 
      self.x_scale=self.create_text(x, 175, font=("", 6),\ 
             anchor='n', text='{}'.format(((12/3) * i)-24)) 

     # y-axis 
     self.vertical=self.create_line(20, 330, 20, 10, width=2) 
     self.y_scale=self.set_y_scale(sinewave_points) 

     if self.y_scale == 100: 
      for i in range(21): 
       self.y = int(330 - (i * (320/20))) #In fact there is an slgorithm to scale the y-axis 
       #print(i, self.y) 
       self.y_axis=self.create_text(17, (self.y), font=("", 6), anchor='e',\ 
           text='{}'.format(int((((200/320)*(320/20)) * i)-\ 
           100))) 


     for i in range(len(sinewave_points)):      
      self.x, self.y = (i+20) , int(-1*self.scale*sinewave_points[i])+ 170 
      self.history=self.create_oval(self.x - 1, self.y - 1, self.x + 1,\ 
             self.y + 1, width=0, fill='purple') 



class Moving_Sinewave(tk.Tk): 
    def __init__(self, *args, **kwargs):   
     #Initialising Tkinter  

     tk.Tk.__init__(self, *args, **kwargs) 
     tk.Tk.wm_title(self, 'Sinewave Moving Plotter') 
     tk.Tk.geometry(self, '800x480')#This is the size of the screen (in pixels)  

     container = tk.Frame(self) 
     container.pack(fill='both', expand= True)#(side="top", fill="both", expand = True) 
     container.grid_rowconfigure (0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 

     for F in (HomePage,     
       SystemConfigPage,     
       ConfigAlarmsPage): 

      frame = F(container, self) 
      self.frames[F] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 
      frame.configure(background= 'ivory2'), 
     self.show_frame(HomePage) 

    def show_frame(self, cont):  
     frame=self.frames[cont] 
     frame.tkraise() 


class HomePage(tk.Frame): 

    def __init__(self, parent, controller): 
     self.controller=controller 
     tk.Frame.__init__(self, parent) 
     global time1, time2, time4, time5 

     sysconfigbutton=tk.Button(self, text= 'System\nConfiguration',   
           command=lambda: controller.show_frame(SystemConfigPage), 
           height=2, width=12) 
     sysconfigbutton.place(x=20, y=80) 

     #graphcanvas=GrpCanvas(tk.Frame)   #works with: class GrpCanvas(tk.Canvas):  
                  #def __init__(self, parent): 
     #graphcanvas=GrpCanvas(HomePage)   #works with: class GrpCanvas(tk.Canvas):  
                  #def __init__(self, parent): 
     #graphcanvas=GrpCanvas(HomePage(tk.Frame)) 

     graphcanvas=GrpCanvas(HomePage, controller.tk)# works with: class GrpCanvas(tk.Canvas):  
                #def __init__(self, parent, controller): 

     graphcanvas.define_graph(graphcanvas.set_y_scale(sinewave_points), sinewave_points) 
    # This actually plots the points 

class SystemConfigPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 

     configalarmsbutton=tk.Button(self, text= 'Configure\nAlarms', 
          command=lambda: controller.show_frame(ConfigAlarmsPage),         
          height=2, width=12) 
     configalarmsbutton.place(x=20, y=180) 

class ConfigAlarmsPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 

     backbutton=tk.Button(self, text= 'Back', 
         command=lambda: controller.show_frame(HomePage), 
           height=2, width=12) 
     backbutton.place(x=20, y=380) 


app = Moving_Sinewave()    
app.mainloop() 

ответ

0

Первый аргумент в GrpCanvas потребности быть родительский виджет, в котором холст должен появиться. В данном конкретном случае вы должны использовать self, так как вы хотите, чтобы быть в домашней странице, и вы создаете его как часть создания HomePage:

graphcanvas=GrpCanvas(self, controller.tk) 

Вы также должны передать этот аргумент дальше к __init__ из родительский класс, который вы пренебрегаете. Чтобы исправить это, изменить это:

tk.Canvas.__init__(self, height=340, ...) 

... к этому:

tk.Canvas.__init__(self, parent, height=340, ...) 

Что происходит, потому, что вы не прошли в родительском, виджет использует корневое окно как по умолчанию. И поскольку вы использовали place, и потому, что этот виджет создавался последним (и, таким образом, был наверху порядка укладки), он отображался поверх всех страниц.

+0

Спасибо, что работает отлично. Я не мог этого видеть. – Oliver

Смежные вопросы