2017-06-01 78 views
0

我是tkinter的新手,我想創建一個帶有「條目」,帶圖片的畫布和按鈕的tkinter接口。我期望只有一個tk窗口,但是當我運行我的代碼時,還有第二個小的空tk窗口。我想這是因爲我使用的類,但我不知道.. 這裏是我的代碼:兩個tk窗口而不是一個

from tkinter import* 
import tkinter as tk 
import time 

class Application(Tk): 
    def __init__(self,transfo,nb_itération): 
     Tk.__init__(self) 
     self.transfo = transfo 
     self.nb_itération = nb_itération 



    def affichage_graphique(self): 

     self.matrix_hex = extraction_rgb(tk.PhotoImage(file='obama_128.gif')) 
     self.width , self.height = len(self.matrix_hex[0]) , len(self.matrix_hex) 
     self.WIDTH, self.HEIGHT = 8*self.width+6, 8*self.height+6 
     self.cnv = Canvas(self, width=self.WIDTH, height=self.HEIGHT, bg='white',highlightthickness=0) 
     self.cnv.grid(row = 2 , columnspan = 3) 
     self.txt1 = Label(self, text = 'Transformation :').grid(row = 0 , sticky = E) 
     self.txt2 = Label(self, text = 'Nombre d\'itérations : ').grid(row = 1 , sticky = E) 
     self.entr1 = Entry(self) 
     self.entr2 = Entry(self) 

     self.entr1.grid(row = 0, column = 1, sticky = W) 
     self.entr2.grid(row = 1, column = 1, sticky = W) 
     Button(self, text="Quitter", command=self.destroy).grid(row = 0 , column = 2) 

     if self.transfo == photomaton or self.transfo == boulanger: 

      print("valeur par défaut mauvaise") 
      self.cnv.delete(ALL) 
      self.img01 = self.PhotoImage(width=self.width*4, height=self.height*4) 
      self.img = self.PhotoImage(width=self.width*4, height=self.height*4) 

      self.matrix_hex4 = [[x for x in range(self.width*4)] for y in range(self.height*4)] 
      self.matrix_4 = [[x for x in range(self.width*4)] for y in range(self.height*4)] 


      self.img.put(data=self.matrix_4 , to=(0,0)) 
      self.cnv.create_image(0, 0, image=self.img, anchor=tk.NW) 

      self.img01.put(data=self.matrix_hex4, to=(0,0)) 
      self.cnv.create_image(self.WIDTH, 0, image=self.img01, anchor=tk.NE) 
      self.cnv.bind('<Button-1>',self.click_handler) 

     else: 

      self.img = tk.PhotoImage(width=self.width*4, height=self.height*4) 
      self.img.put(data=self.matrix_4 , to=(0,0)) 
      self.cnv.create_image(0, 0, image=self.img, anchor=tk.NW) 
      self.entr1.insert(0,"photomaton") 
      self.entr2.insert(0,"1") 
      self.entr2.bind("<Return>",Programme().Enter) 



class Programme(Application): 
    def __init__(self,transfo = 0, nb_itération = 0 ,orbites =[],période = []): 
     self.choice = 0 
     self.orbites = orbites 
     self.période = période 
     self.transfo = transfo 
     self.nb_itération = nb_itération 
     Application.__init__(self, self.transfo , self.nb_itération) 


    def Enter(self,event): 
     self.choix_transfo = self.entr1.get() 
     self.nb_itération = self.entr2.get() 
     return self.choix_transfo , self.nb_itération 

    def start(self): 
     self.affichage_graphique() 



prog = Programme() 
prog.start() 
prog.mainloop() 
+1

有一對夫婦在你的代碼,阻止我運行它的錯誤,請發表[最小的,完整的,和可驗證示例](https://stackoverflow.com/help/mcve)。例如,'Program .__ init__'在參數列表後面缺少冒號。另外,在'Program .__ init__'中有一個無限遞歸。 – FamousJameous

+0

我的猜測是(a)你有幾個類都擴展了'Tk',或者(b)你有一個類擴展了'Tk'並且還手動創建了一個「root」Tk實例。但是,不能檢查,因爲你的代碼有錯誤(語法和運行時)。我建議不要擴展'Tk',而是'Frame'。 –

+0

代碼中沒有任何內容會創建兩個窗口。不過,我看到你使用'Program()',但沒有這個名字的類或函數。你有一個名爲「程序」的課程 - 是否是其中一個錯誤? –

回答

2

的問題似乎是在這條線:

self.entr2.bind("<Return>",Programme().Enter) 

此行有多個問題:

  1. 它會創建一個Program()實例(假設這是一個錯字),因此形成了第二窗口Tk (因爲Program延伸Tk
  2. 它會這麼做立即,按鈕被點擊時不僅,而且新實例的方法綁定到按鈕

相反,你可能想使用

self.entr2.bind("<Return>", self.Enter) 

調用當前Program實例的Enter方法,或

self.entr2.bind("<Return>", lambda: Program().Enter) 

如果你實際上想要創建第二個Program窗口時點擊按鈕;但是,在這種情況下,您還需要調用gui方法才能初始化窗口小部件。


注意有代碼中的其他一些問題,如在評論中討論,但我認爲,那些不實際的代碼存在,否則你不會得到這種行爲。

+0

我編輯了我的問題並添加了完整的代碼。 –

1

您正在兩處創建一個新窗口。首先,這樣的:

prog = Programme() 

第二個是在這裏:

self.entr2.bind("<Return>",Programme().Enter) 

爲什麼?上面的代碼在功能上與此相同:

p = Programme() 
self.entr2.bind("<Return>", p.Enter) 

調用程序類中定義的函數的正常方法是使用現有引用。因爲你的代碼是在屬於Programme類的方法中運行,你可以這樣做:

self.entr2.bind("<Return>", self.Enter) 
+0

「entry.bind」方法創建一個窗口?我能做些什麼來避免這種情況?在應用程序類中放入「Enter」? –

+0

Thx爲您提供幫助! –

+0

@NathanDubois:no,'entry.bind'不會創建一個窗口,'Program().Enter'會生成一個窗口,因爲Program()會創建一個窗口。 –

相關問題