2016-06-01 4 views
0

Я пытаюсь сделать своего рода графический интерфейс с tkinter, и вот код. Но, когда я запустил его, нажмите настройки, а затем обратно, сбой python. Вы не знаете, почему это может произойти и как я это исправит? Это происходит, когда я или запустить функцию уничтожения, или когда я делаю что-то в другом окне Tk,Tkinter destroy метод сбрасывает программу

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

import tkinter as tk 

class moveFrame(): 
    def move(self, event): 
     widget = event.widget 
     widget.place(x = widget.winfo_x() + event.x - widget.startX, y = widget.winfo_y() + event.y - widget.startY) 

def resize(self, event): 
    widget = event.widget 
    wlength = widget["length"] 
    wwidth = widget["width"] 
    widget.config(length = wlength + event.x - widget.startX, width = wwidth + event.y - widget.startY) 

def getPos(self, event): 
    widget = event.widget 
    widget.lift() 
    widget.startX, widget.startY = event.x, event.y 

def __init__(self, master, frameInfo, xPos, yPos): 
    self.frame = tk.Frame(master, cnf = frameInfo) 
    self.frame.bind("<Button-1>", self.getPos) 
    self.frame.bind("<B1-Motion>", self.move) 
    self.frame.bind("<B3-Motion>", self.getPos) 
    self.frame.bind("<Button-3>", self.resize) 
    self.frame.place(x = xPos, y = yPos) 


def homescreen(): 
    screen = tk.Tk() 
    #arrangeButton = tk.Canvas(screen, width = 120, height = 40, bg = "purple") 
    #arrangeButton.create_text(60, 20, text = "Arrange Homescreen") 
    #arrangeButton.place(x = 0, y = 0) 
    #arrangeButton.bind("<Button-1>", lambda event: arrange(arrangeButton)) 
    settingsButton = tk.Canvas(screen, width = 60, height = 60) 
    settingsButton.place(x = 20, y = 20) 
    settingsButton.create_oval(5, 5, 58, 58, fill = "#a6a6a6", tags = "click") 
    settingsButton.create_oval(15, 10, 58, 53, fill = "#000", tags = "click") 
    settingsButton.create_oval(27, 22, 46, 41, fill = "#00f", tags = "click") 
    settingsButton.tag_bind("click", "<Button-1>", lambda event: settings()) 

def settings(): 
    sscreen = tk.Tk() 
    #Get previous settings 
    try: 
     file = open("settings.txt", "r") 
    except IOError: 
     file = open("settings.txt", "x") 
    finally: 
     file = open("settings.txt", "r+") 
    curSet = [x.strip("\n") for x in file.readlines()] 
    #Widgets 
    back = tk.Canvas(sscreen, width = 60, height = 48) 
    back.place(x = 20, y = 20) 
    back.create_rectangle(25, 22, 60, 26, fill = "#000", tags = "sclick") 
    back.create_polygon(10, 24, 25, 10, 25, 38, fill = "#000", tags = "sclick") 
    back.create_text(42, 32, text = "Back", tags = "sclick") 
    back.tag_bind("sclick", "<Button-1>", lambda event: sscreen.destroy()) 

def arrange(*widgets): 
    arrangeScreen = tk.Tk() 
    arrangeButton = widgets[0] 
    aBaF = moveFrame(arrangeScreen, {"bd" : 4, "bg" : "#a6a6a6"}, arrangeButton.winfo_x() - 4, arrangeButton.winfo_y() - 4) 
    aBa = tk.Canvas(aBaF, width = 120, height = 40, bg = "purple") 


def load(goTo, ms): 
    load = tk.Tk() 
    loadImage = tk.Canvas(load, height = 300, width = 300, bg = "black") 
    loadImage.pack() 
    loadImage.create_oval(125, 130, 175, 180, fill = "white") 
    loadImage.create_oval(130, 140, 170, 150, fill = "black") 
    loadImage.create_oval(130, 140, 171, 151, fill = "white") 
    loadImage.create_oval(152, 140, 148, 150, fill = "black") 
    load.after(ms, lambda: [goTo(), load.destroy()]) 

load(homescreen, 1) 
+1

Минимальный пример и обратная трассировка пройдут долгий путь. –

+0

Вы запускаете этот скрипт в IDLE? –

+0

Что означает «python crashes»? Вы получаете трассировку стека? Кроме того, отступы в вашем примере кода нарушены. –

ответ

1

Если ваш программа представляет собой одно приложение, создавая только один экземпляр Tk.

Объект Tk представляет корень всего приложения, удаляя его и создавая другой, который вы по существу создаете отдельное приложение, и любые ссылки на предыдущее приложение приводят к неопределенному поведению, например, к сбою python.

Вместо использования Tk в качестве отдельных окон используйте Toplevel, поскольку они предназначены для отдельных окон.

Заменяя все вхождения tk.Tk() в вашей программе с tk.Toplevel(abs_root) последующим определением abs_root, как tk.Tk(), как это:

abs_root = tk.Tk() 
abs_root.withdraw() #hides the window while your program runs. 
load(homescreen, 1) 
abs_root.mainloop() 

Сделает вашу программу работу, однако это не означает, что он будет работать до тех пор, abs_root не будет уничтожен, который не может произойдет, нажав кнопку закрытия, так как он не отображается как окно, вам придется либо использовать какое-то условие, в котором вы явно вызываете abs_root.destroy(), либо выбираете одно окно, которое будет первым созданным и последним, которое будет закрыто, и используйте это вместо abs_root , (невозможно с вашей программой, как написано)

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