2015-02-07 4 views
0

У меня есть игра, над которой я работаю, используя текст, чтобы сообщить пользователю, что происходит в игре. Тем не менее, я использую окно Tkinter для включения ввода с помощью кнопок, для более профессионального восприятия. Я также включил несколько ярлыков, но все они упаковываются в новое окно, а не то, что я уже сделал. Не спрашивайте о именах переменных, но это код:Почему мои виджеты tkinter упаковываются в неправильное окно?

def scan(): 
    action=str('scan') 
    TSGcontrols.destroy() 
    return action 
def lookaround(): 
    action=str('look around') 
    TSGcontrols.destroy() 
    return action 
def visoron(): 
    action=str('engage visor') 
    global firstvisor 
    if firstvisor==1: 
     firstvisor=int(0) 
     print ('The visor has a colour code.') 
     print ('It displays a wire frame over black, based on sensor data -\nallowing you to see through walls (to a degree).') 
     print ('\nColours:') 
     print ('Green = inert object') 
     print ('Blue = electrical signature') 
     print ('Red = weapon signature') 
     print ('Yellow = radiation (the darker the yellow, the deadlier exposure would be)') 
     print ('White = life (the more grey, the weaker the lifesigns. Dark grey is dead.)') 
     print ('Purple = unidentified\n') 
    TSGcontrols.destroy() 
    return action 
def visoroff(): 
    action=str('disengage visor') 
    TSGcontrols.destroy() 
    return action 
def personbasecreate(): 
    global TSGcontrols 
    TSGcontrols=tkinter.Tk(screenName='/TSGcontrols',baseName='/TSGcontrols',className='/TSGcontrols') 
    warning=Label(text='This is only the control panel for TSG.\nThe game\'s responses are output in the Python window.',bg='red') 
    global location 
    locationw=Label(text='Location: {0}'.format(location)) 
    controlling=Label(text='You are controlling only yourself.',bg='blue',fg='white') 
    lookaround=Button(text='Look around',command=lookaround) 
    visoron=Button(text='Turn visor on',command=visoron) 
    visoroff=Button(text='Turn visor off',command=visoroff) 
    scan=Button(text='Scan',command=scan) 
    warning.pack(parent=TSGcontrols,side='top') 
    locationw.pack(parent=TSGcontrols,side='top') 
    controlling.pack(parent=TSGcontrols,side='top') 
    lookaround.pack(side='left') 
    scan.pack(side='left') 
    if visor=='on': 
     visoroff.pack(parent=TSGcontrols,side='right') 
    else: 
     visoron.pack(parent=TSGcontrols,side='right') 
    groupw.pack(parent=TSGcontrols,side='bottom') 

Тогда позже:

addbutton1 = str('no') 

while repeat==str('yes'): 
    time.sleep(3) 
    print ('\nChoose your action.') 
    # Creating the basic window: 
    personbasecreate() 
    if addbutton1=='yes': 
     # Adding the additional function: 
     leavequarters.pack(in_=personGUI,side='left') 
    action=str(personGUI.mainloop()) 

Но вместо виджетов, появляющихся в окне под названием «TSG Controls», они появляются в новый, называемый «tk» - поэтому, когда окно уничтожается, чтобы обработать переменную «действие», она уничтожает пустое окно, и игра вылетает из-за того, что функции пытаются уничтожить окно, которого там нет, бросая ошибка:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "D:\Python\lib\tkinter\__init__.py", line 1489, in __call__ 
    return self.func(*args) 
    File "D:\Python\TSG.py", line 881, in lookaround 
    personGUI.destroy() 
    File "D:\Python\lib\tkinter\__init__.py", line 1849, in destroy 
    self.tk.call('destroy', self._w) 
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed 

Когда кнопка «Оглядеться» нажата дважды.

Есть ли способ исправить этот код или более простой способ сделать то, что я пытаюсь выполнить здесь?

+0

Если вы упорядочиваете свой код лучше, используя как минимум 1 пробел между определениями функции, это может помочь нам разобраться в проблеме. – nbro

+0

Зачем вам нужны функции внутри других функций? Я почти никогда их не использовал, я не знаю, зачем вам это нужно. – nbro

+0

@ Ринцлер, наверное, я этого не делаю. Я отредактирую это. –

ответ

1

Часть проблемы, вероятно, это:

personGUI=tkinter.Tk(className='/TSG Controls') 
warning=Label(text='This is only the control panel for TSG.\nThe game\'s responses are output in the Python window.',bg='red') 

Обратите внимание, что вы создаете новое корневое окно, но затем создать ярлык без указания родителя. Вы всегда должны указывать родителя для виджета, и вы всегда должны создавать только один экземпляр Tk для всего вашего приложения. Если вам нужно создать несколько окон, создайте одно корневое окно один раз, а затем для других окон вам нужно создать экземпляры tkinter.Toplevel.

+0

Спасибо - не могли бы вы дать синтаксис для указания родителя? –

+0

@OliverPotts: предоставить родительскому элементу первый аргумент при создании виджетов: 'warning = Label (personGUI, ...)' –

+0

Теперь он бросает «Traceback (последний последний вызов): Файл« D: \ Python \ TSG. ру "строка 1118, в personbasecreate() Файл "D: \ Python \ TSG.py", строка 917, в personbasecreate warning.pack (personGUI, сторона = 'сверху') Файл" D: \ Python \ lib \ tkinter \ __ init__.py ", строка 1927, в файле pack_configure + self._options (cnf, kw)) _tkinter.TclError: неверный вариант« -контейнер »: должен быть -после, -anchor, -before, - expand, -fill, -in, -ipadx, -ipady, -padx, -pady или -side' –