wxpython - 如果程序中发生某些事情,如何使按钮禁用?
wxpython - How to make buttons disable if something in the programm happens?
我正在为学校的一个项目编程,我有点陷入了我无法解决的非常简单的事情。该程序是 BULLS AND COWS 游戏的 GUI。
我用数字按钮来做,每次点击每个按钮,都会将所选数字添加到文本框。由于游戏规则,在回合结束之前必须只有 4 个数字,所以我想做的是,如果文本框中已经有 4 个数字,则禁用按钮。
这是代码:
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")?我知道命令 button.Disable(),但我不知道该把它放在哪里才能让它工作,而且我所有的尝试都失败了。
我希望你能帮助我.. :)
要在计数器达到 4 时禁用所有按钮,请在容器上使用 GetChildren()
方法。在本例中,即 self.panel
,它是所有按钮的父级。不过,简单地调用 self.panel.GetChildren()
会给你 所有 个子项,而不仅仅是按钮。
幸运的是,Python 具有内置函数 isinstance()
来检查对象是否属于给定的 class。为了确保我们只禁用按钮,我们检查 isinstance(button, wx.Button)
returns 是否为真,表明该对象确实是 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),我们忽略它;如果是,我们将其禁用。
希望对您有所帮助!
我正在为学校的一个项目编程,我有点陷入了我无法解决的非常简单的事情。该程序是 BULLS AND COWS 游戏的 GUI。 我用数字按钮来做,每次点击每个按钮,都会将所选数字添加到文本框。由于游戏规则,在回合结束之前必须只有 4 个数字,所以我想做的是,如果文本框中已经有 4 个数字,则禁用按钮。 这是代码:
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")?我知道命令 button.Disable(),但我不知道该把它放在哪里才能让它工作,而且我所有的尝试都失败了。
我希望你能帮助我.. :)
要在计数器达到 4 时禁用所有按钮,请在容器上使用 GetChildren()
方法。在本例中,即 self.panel
,它是所有按钮的父级。不过,简单地调用 self.panel.GetChildren()
会给你 所有 个子项,而不仅仅是按钮。
幸运的是,Python 具有内置函数 isinstance()
来检查对象是否属于给定的 class。为了确保我们只禁用按钮,我们检查 isinstance(button, wx.Button)
returns 是否为真,表明该对象确实是 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),我们忽略它;如果是,我们将其禁用。
希望对您有所帮助!