wxpythonframewxgrid

How to add a grid to my program without that all of the rest of the program will be deleted?


This is my code:

import wx
import wx.grid as gridlib
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




    # 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 disable_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)
        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.
            for i in range(12):
                if event.Id != -31981 and event.Id != -31979 and event.Id == OPTIONS_ID[i]:
                    self.fdf.AppendText(str(OPTIONS[i]))
                    self.count += 1
                elif event.Id == -31979:
                    pass
            if event.Id == -31981:
                if self.count > 0:
                    self.count -= 1
                self.fdf.Remove(self.fdf.GetLastPosition()-1, self.fdf.GetLastPosition())
            if self.count == 4:
                for child in self.panel.GetChildren():
                    if isinstance(child, wx.Button):
                        try:
                            int(child.GetLabel())
                        except ValueError:
                            if child.GetLabel() == "SEND":
                                child.Enable()
                        else:
                            child.Disable()
            else:
                for child in self.panel.GetChildren():
                    if child.GetLabel() != "SEND":
                        child.Enable()
                    else:
                        child.Disable()
                    if self.count == 0:
                        if child.GetLabel() == "DEL":
                            child.Disable()
            for child in self.panel.GetChildren():
                if isinstance(child, wx.Button):
                    if child.GetLabel() in self.fdf.GetValue():
                        child.Disable()



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!", (20, 20), size=(35))
        countX = 500
        countY = 100
        for option in OPTIONS:
            if str(option) == "SEND" or str(option) == "DEL":
                window.disable_button(first_panel,str(option), (countX, countY), 100, 100)
            else:
                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()

What I am trying to do is to add a grid into the empty area, but for some reason the grid is shown in the whole frame, which hide the the other attributes of the panel. My question is how to add the grid normally to the panel, I mean without ruin the other program? I have tried to play with the position but for some reason it doesn't work, and I didn't find any information in the internet. I will glad to get some help here. Thank you (: By the way: the grid is with 10 rows and 3 cols.


Solution

  • If I've understood you the right way it should work like this:

    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
    
            #This lines of code add the grid to the frame
            grid = gridlib.Grid(first_panel) #the grid must created with a panel as argument  
            grid.CreateGrid(10,3) #create grid with 10 rows and 3 columns
            sizer = wx.BoxSizer(wx.HORIZONTAL)  
            sizer.Add(grid, 0, wx.ALIGN_CENTER|wx.ALL, 50) #Border in all directions with 50 pixels width
            first_panel.SetSizer(sizer)  
            #grid has been added to the frame... continuing with your code         
    
            window.write(first_panel, "BULLS AND COWS!", (20, 20), size=(35))
            countX = 500
            countY = 100
    ...
    

    You can also add the grid in a function of your Frame class it should work similar and depends on your application. I think the success of adding a grid without "destroying" the rest of your frame depends on the sizer. With the arguments above it should work.