Hello, I'm re-creating the game Riveter using wxPython. I have all the basic fundamental groundwork done, and now I'm just trying to polish certain aspects. I am, however, having problems removing buttons from the screen.
I have a panel, with a vertical sizer inside of it. Inside of that vertical sizer are multiple horizontal sizers, as seems to be the basic way to do things from the "starting wxPython" sticky thread. Additionally inside the vertical sizer is a wx.GridSizer, with which each cell has a button inside of it (with parent of the panel.) Now, when a new game is started, I try to remove the wx.GridSizer and replace it with another one. What happens is that the buttons stick around, now completely locked into the place they were, regardless of resizing the window, along with new buttons belonging to the new GridSizer under them. I realize this may be hard to follow, but I have included my code below.
My question is how do i remove these buttons, along with the GridSizer that they're contained in?
Along a related note, I've noticed some weird behavior with the windowing, and I was hoping for some light to be shed.
1- Under WINDOWS, whenever the program is started, all the objects are stuck in the top-left corner until the window is resized, or the game is started. Everything is placed fine after that.
2- In LINUX, everything is placed correctly at the start, but when a game is started, the statusInfo sizer disappears.
Both Windows and Linux are both running the newest wxPython versions, and both the same python 2.7 version.
Once again, I appreciate any help you can give. Thank you!
PS- I was trying to follow the GridSizer example here: http://www.daniweb.com/software-development/python/threads/128350/648463#post648463
import wx
from functools import partial
PROG_VER = 1.0
class Main(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title = 'Justin!', size=(800,600))
self.background = wx.Panel(self)
#Menubar
self.menuBar = wx.MenuBar()
self.SetMenuBar(self.menuBar)
self.menuFile = wx.Menu()
self.menuInfo = wx.Menu()
self.menuBar.Append(self.menuFile, 'File')
self.menuBar.Append(self.menuInfo, 'Info')
self.newItem = self.menuFile.Append(-1, 'New Game')
self.Bind(wx.EVT_MENU, self.newEvent, self.newItem)
self.exitItem = self.menuFile.Append(-1, 'Exit')
self.Bind(wx.EVT_MENU, self.exitEvent, self.exitItem)
self.instruItem = self.menuInfo.Append(-1, 'Instructions')
self.Bind(wx.EVT_MENU, self.instruEvent, self.instruItem)
self.aboutItem = self.menuInfo.Append(-1, 'About')
self.Bind(wx.EVT_MENU, self.aboutEvent, self.aboutItem)
#Sections
self.displayInfo = wx.BoxSizer()
self.displayText = wx.StaticText(self.background, -1, "placeholder")
self.displayInfo.Add(self.displayText, proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
self.statusInfo = wx.BoxSizer()
self.coinsText = wx.StaticText(self.background, -1, "Coins left: ", style = wx.ALIGN_RIGHT)
self.numberText = wx.TextCtrl(self.background, -1, "0", style = wx.TE_READONLY)
self.statusInfo.AddStretchSpacer(1)
self.statusInfo.Add(self.coinsText, proportion = 0, border = 0)
self.statusInfo.Add(self.numberText, proportion = 0, border = 0)
self.gridSizer = wx.BoxSizer()
self.vertBox = wx.BoxSizer(wx.VERTICAL)
self.vertBox.Add(self.displayText, proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
self.vertBox.Add(self.gridSizer, proportion = 1, flag = wx.EXPAND, border = 0)
self.vertBox.Add(self.statusInfo, proportion = 0, border = 0)
self.background.SetSizer(self.vertBox)
self.vertBox.Layout()
self.Show()
self.Bind(wx.EVT_CLOSE, self.onCloseWindow)
def exitEvent(self, event):
# via wx.EVT_CLOSE event, also triggers exit dialog
self.Close(True)
def onCloseWindow(self, event):
# dialog to verify exit (including menuExit)
dlg = wx.MessageDialog(self, "Want to exit?", "Exit", wx.YES_NO | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
self.Destroy() # frame
dlg.Destroy()
def instruEvent(self, event):
pass
def newEvent(self, event):
self.players = []
self.height, self.width, self.players_amount = 0, 0, 0
self.board = []
self.coins_left = 0
self.getInfo()
try: self.gridSizer.Remove(self.grid)
except: print "not here"
try: del self.grid
except: pass
self.grid = Board()
self.grid.setup(self.width, self.height)
self.gridSizer.Add(self.grid, proportion = 1, border= 0)
self.gridSizer.Layout()
self.gridSizer.Fit(self)
self.vertBox.Layout()
self.vertBox.Fit(self)
self.turn_number = self.players_amount
self.gamePlay()
def aboutEvent(self, event):
pass
def getInfo(self):
dialogBox = wx.TextEntryDialog(None, "How many players will there be?", "Players", "2")
if dialogBox.ShowModal() == wx.ID_OK:
self.players_amount = int(dialogBox.GetValue())
for loop in range(self.players_amount):
dialogBox = wx.TextEntryDialog(None, "What will the name of player %i be?"%(loop+1, ), "Player Names", "Player %i"%(loop+1, ))
if dialogBox.ShowModal() == wx.ID_OK:
self.players.append(dialogBox.GetValue())
dialogBox = wx.TextEntryDialog(None, "How many rows will there be?", "Height", "3")
if dialogBox.ShowModal() == wx.ID_OK:
self.height = int(dialogBox.GetValue())
dialogBox = wx.TextEntryDialog(None, "How many columns will there be?", "Width", "3")
if dialogBox.ShowModal() == wx.ID_OK:
self.width = int(dialogBox.GetValue())
def gamePlay(self):
for i in range(self.players_amount):
if self.turn_number % self.players_amount == i:
self.turn(self.players[i])
self.turn_number += 1
def endGame(self):
for i in range(self.players_amount):
if self.turn_number % self.players_amount == i:
if i != 0:
self.displayText.SetLabel("You win, %s!"%(self.players[i], ))
else:
self.displayText.SetLabel("You win, %s!"%(self.players[self.players_amount-1], ))
def turn(self, player):
if self.status == 3: return 0
self.coins_left = 3
self.displayText.SetLabel("Your turn, %s!"%(player, ))
self.statusInfo.Clear()
self.numberText.ChangeValue(str(self.coins_left))
def status(self):
count = 0
for i in range(self.height):
for j in range(self.width):
if (self.grid.board[i][j] == 0):
count += 1
if (count == 0): return 1
else: return 0
class Board(wx.GridSizer):
def __init__(self):
wx.GridSizer.__init__(self, 2, 2, 2, 2)
self.height, self.width = 0, 0
self.board = []
def setup(self, width, height):
self.width, self.height = width, height
try: del self.gridButtons
except: pass
self.gridButtons = range(self.width * self.height)
self.SetCols(self.width)
self.SetRows(self.height)
for i in range(self.height):
inside_array = []
for j in range(self.width):
#The following adds the edge coins.
if (i == 0): inside_array.append(0)
elif (i == (self.height - 1)): inside_array.append(0)
elif (j == 0): inside_array.append(0)
elif (j == (self.width - 1)): inside_array.append(0)
#But this removes all others.
else: inside_array.append(1)
self.board.append(inside_array)
count = 0
for i in range(self.height):
for j in range(self.width):
idnum = 100 + count
if (self.board[i][j] == 0):
self.gridButtons[count] = wx.Button(window.background, idnum, label = "X")
self.Add(self.gridButtons[count], 0, wx.ALL|wx.EXPAND, border = 1)
self.gridButtons[count].Bind(wx.EVT_BUTTON, partial(self.buttonClick, number = count, i = i, j = j))
if (self.board[i][j] == 1):
self.gridButtons[count] = wx.Button(window.background, idnum, label = " ")
self.Add(self.gridButtons[count], 0, wx.ALL|wx.EXPAND, border = 1)
count += 1
def buttonClick(self, event, number, i, j):
self.gridButtons[number].SetLabel("")
self.gridButtons[number].Unbind(wx.EVT_BUTTON)
self.board[i][j] = 1
window.coins_left -= 1
if window.coins_left == 0: window.gamePlay()
window.statusInfo.Clear()
window.numberText.ChangeValue(str(window.coins_left))
if window.status() == 1: window.endGame()
app = wx.App(redirect = False)
window = Main()
app.MainLoop()