2016-04-21 1 views
2

Я программирую проект в школе, и я как бы застрял в очень простой вещи, которую я просто не могу решить. программа представляет собой графический интерфейс игры BULLS AND COWS. Я делаю это с помощью кнопок цифр, каждый щелчок по каждому из них добавляет выбранный номер в текстовое поле. Из-за правил игры должно быть всего 4 номера до окончания хода, поэтому я пытаюсь сделать кнопки отключенными, если в текстовом поле уже есть 4 номера. Вот код:wxpython - Как сделать кнопки отключенными, если что-то в программе происходит?

import wx 
from random import randint 

OPTIONS = [1, 2, 3, 4, 5, 6, 7, 8, 9, "DEL", 0, "SEND"] 
# these are the events' IDs sent to a function when you click a button. 
# the OPTIONS_ID is in the same order of OPTIONS. 

OPTIONS_ID = [-31990,-31989,-31988,-31987,-31986,-31985, -31984, -31983, -31982, -31981, -31980, -31979] # the built in wxpython IDs for the buttons 


GAME_POSITION = (400, 100) 
GAME_SIZE = [900, 600] 

class Frame(wx.Frame): # class for all the frames in our game. 

    def __init__(self, parent, id, title, pos, size): 
     wx.Frame.__init__(self, parent, id, title, pos, size) 
     self.panel = wx.Panel(self) 
     self.fdf = wx.TextCtrl(self.panel, size=(275, 75), pos=(520, 20)) 
     self.count = 0 
     self.check = False 
    # this function creates a textbox at a specific position with a specific size. 
    def write(self, panel, txt, pos, size=20, font_family=wx.SWISS, font_style = wx.NORMAL,font_weight = wx.BOLD, underline = False): 
     # create a textbox at a specific position with a specific size. 
     your_txt = wx.StaticText(panel, -1, txt, pos) 
     your_txt.SetFont(wx.Font(size,font_family,font_style,font_weight,underline)) 
    # same as above, just for a button. 
    def create_button(self, panel, txt, position, width, height): 
     Size = wx.Size(width, height) 
     self.button = wx.Button(panel, -1, txt, position, Size) 
     self.border = wx.BoxSizer(wx.VERTICAL) 
     self.border.Add(self.button) 
     self.Bind(wx.EVT_BUTTON, lambda evt: self.OnButton(evt), self.button) 
    def create_disable(self, panel, txt, position, width, height): 
     Size = wx.Size(width, height) 
     self.button = wx.Button(panel, -1, txt, position, Size) 
     self.border = wx.BoxSizer(wx.VERTICAL) 
     self.border.Add(self.button) 
     self.button.Disable() 
    def OnButton(self, event): 
     print repr(event.Id) + "," 
     if event.Id in OPTIONS_ID: # if indeed an option button was pressed 
      exited = -1 # exited is 5100 if the user exited his dialog box 
      # assigning the events to the button. 
      if event.Id == OPTIONS_ID[0]: # 1 
       self.fdf.AppendText(str(OPTIONS[0])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[1]: # 2 
       self.fdf.AppendText(str(OPTIONS[1])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[2]: # 3 
       self.fdf.AppendText(str(OPTIONS[2])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[3]: # 4 
       self.fdf.AppendText(str(OPTIONS[3])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[4]: # 5 
       self.fdf.AppendText(str(OPTIONS[4])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[5]: # 6 
       self.fdf.AppendText(str(OPTIONS[5])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[6]: # 7 
       self.fdf.AppendText(str(OPTIONS[6])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[7]: # 8 
       self.fdf.AppendText(str(OPTIONS[7])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[8]: # 9 
       self.fdf.AppendText(str(OPTIONS[8])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[9]: # del 
       if self.count > 0: 
        self.count -= 1 
       self.fdf.SetValue(self.fdf.GetValue()[:-1]) 
      elif event.Id == OPTIONS_ID[10]: # 0 
       self.fdf.AppendText(str(OPTIONS[10])) 
       self.count += 1 
      elif event.Id == OPTIONS_ID[11]: # send 
       self.fdf.AppendText(str(OPTIONS[11])) 
      if self.count == 4: 
       print "ddd" 


class Game(wx.App): 
    def OnInit(self): # upon game opening 
     # I would like the options window to be the first window's parent 
     # so I will first set up our options window: 
     window = Frame(None, -1, "Good Luck!", GAME_POSITION, GAME_SIZE) 
     first_panel = window.panel 
     window.write(first_panel, "BULLS AND COWS!", (50, 50), size=(35)) 
     countX = 500 
     countY = 100 
     for option in OPTIONS: 
      window.create_button(first_panel,str(option), (countX, countY), 100, 100) 
      countX += 110 
      if str(option) == "3" or str(option) == "6" or str(option) == "9": 
       countY += 110 
       countX = 500 



     window.Show(True) 
     return True 


def main(): 
    camel = Game() 
    camel.MainLoop() 


if __name__ == '__main__': 
    main() 

Я пытался сделать это с помощью счетчика переменного подсчета каждого нажатия одной из кнопок, и когда он равен 4 (это означает, что есть 4 номер в текстовом поле) , то что-то происходит (в коде я сказал ему напечатать строку «ddd» без причины). Вопрос в следующем: как я могу отключить кнопки, когда есть 4 номера (вместо печати «ddd»)? Я знаю кнопку command.Disable(), но я понятия не имею, куда ее поместить, чтобы заставить ее работать, и я не смог выполнить все мои попытки.

Я надеюсь, что вы мне помочь .. :)

+0

Просто уточните: как только счетчик достигнет 4, вы хотите отключить * все * кнопки? – dpwilson

+0

все кнопки с номерами (конечно, можно нажать кнопки «удалить» и «отправить»). – omer

ответ

0

Чтобы отключить все кнопки, как только счетчик достигнет 4, используйте метод GetChildren() на контейнере. В этом случае это self.panel, который является родительским для всех кнопок. Просто позвоните self.panel.GetChildren() даст вам все детей, правда, не только кнопки.

К счастью, у Python есть встроенная функция isinstance(), чтобы проверить, является ли объект данного класса. Чтобы убедиться, что мы только отключаем кнопки, мы проверяем, что isinstance(button, wx.Button) возвращает true, указывая, что объект действительно является экземпляром wx.Button.

Ограничение этого на пустые кнопки затрудняет его, но не слишком. Просто проверьте ярлык кнопки! Вот как вы можете это сделать:

... 
if self.count == 4: 
    for child in self.panel.GetChildren(): 
     if isinstance(child, wx.Button): 
      try: 
       int(child.GetLabel()) 
      except ValueError: 
       pass 
      else: 
       child.Disable() 
... 

Во-первых, мы прокручиваем все дочерние элементы вашей панели. На следующей строке мы проверяем, действительно ли ребенок на самом деле кнопка, а не статический текст или что-то в этом роде. Наконец, мы проверяем, является ли метка целой. Если это не так (и это вызывает значение ValueError), мы игнорируем его; если это так, мы его отключим.

Надеюсь, это поможет!

+0

Большое спасибо! это работает отлично. Как я могу узнать больше об этой теме (что такое дети и родители и как их использовать)? Я думаю, что это будет очень полезно для меня .. – omer

+0

Теперь я заметил небольшую ошибку. если я поставил 4 номера, он работает точно так же, как я хочу (отключить все кнопки с номерами), но если после этого я удалю один число, чем счет становится до 3 - но кнопки с номерами по-прежнему отключены. как я могу это исправить? И вот я хочу сказать, что английский не мой родной язык, поэтому у меня, наверное, есть ошибки в грамматизме .. sory;) – omer

+0

Я исправил это сам! извините за ненужный вопрос .. Ха-ха И снова, если вы за свою помощь, я действительно ценю это. – omer