0

I am new to Tkinter and I want to create a button which when pressed displays a 2nd interface. I have written the following program:

import Tkinter

root = Tkinter.Tk(  )
root.title("My First Game")

for r in range(3):
    for c in range(3):
            Tkinter.Label(root, text= '3', borderwidth=20 ).grid(row=1,column=1)
        Tkinter.Label(root, text= '6', borderwidth=20 ).grid(row=1,column=2)
        Tkinter.Label(root, text= '4', borderwidth=20 ).grid(row=1,column=3)
        Tkinter.Label(root, text= '2', borderwidth=20 ).grid(row=2,column=1)
        Tkinter.Label(root, text= '7', borderwidth=20 ).grid(row=2,column=2)
        Tkinter.Label(root, text= ' ', borderwidth=20 ).grid(row=2,column=3)
        Tkinter.Label(root, text= '5', borderwidth=20 ).grid(row=3,column=1)
        Tkinter.Label(root, text= '1', borderwidth=20 ).grid(row=3,column=2)
        Tkinter.Label(root, text= '8', borderwidth=20 ).grid(row=3,column=3)

def mainprg():
    for r in range(3):
        for c in range(3):
            Tkinter.Label(root, text= '3', borderwidth=20 ).grid(row=1,column=1)
            Tkinter.Label(root, text= '6', borderwidth=20 ).grid(row=1,column=2)
            Tkinter.Label(root, text= ' ', borderwidth=20 ).grid(row=1,column=3)
            Tkinter.Label(root, text= '2', borderwidth=20 ).grid(row=2,column=1)
            Tkinter.Label(root, text= '7', borderwidth=20 ).grid(row=2,column=2)
            Tkinter.Label(root, text= '4', borderwidth=20 ).grid(row=2,column=3)
            Tkinter.Label(root, text= '5', borderwidth=20 ).grid(row=3,column=1)
            Tkinter.Label(root, text= '1', borderwidth=20 ).grid(row=3,column=2)
            Tkinter.Label(root, text= '8', borderwidth=20 ).grid(row=3,column=3)


B = Tkinter.Button(text = "Run", command = mainprg)
B.pack()

root.mainloop()

I am trying to display the first interface and the Run button. After pressing the Run button the 2nd interface is to be displayed. But after running the above code, it does not display anything.

matsjoyce
  • 5,744
  • 6
  • 31
  • 38
bio-terror
  • 35
  • 7

2 Answers2

1

You are mixing grid and pack (this is a bad idea, see e.g. https://stackoverflow.com/a/3968033/3001761); change the assignment of B to:

B = Tkinter.Button(text = "Run", command = mainprg)
B.grid(row=4, column=1)

Also, your for loops do the same thing 9 times for no apparent reason; you should probably re-think the logic.

Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • What should i do if i want to display a series of interfaces like the above with just a single hit of the Run button? – bio-terror Oct 10 '14 at 11:53
  • @bio-terror I don't really know what you're trying to achieve, but you might find this useful: http://stackoverflow.com/a/26213779/3001761 – jonrsharpe Oct 10 '14 at 12:49
  • I created 4 interfaces for my program but after clicking the Run button, it directly jumps to the 4th interface without considering the 2nd and 3rd ones. – bio-terror Oct 10 '14 at 13:41
  • @bio-terror what, exactly, are you expecting me to do? Guess what code you've written? If you have a new question, please ask it (via this handy checklist: http://meta.stackoverflow.com/q/260648/3001761). – jonrsharpe Oct 10 '14 at 13:43
0

Here is an example that make a part of what you are trying to do. Note the use a a list of reference to label that have to be replaced. If no use of clean method is done, then you just "overwrite" the previous screen appearance and it can lead to broken interface where part of button are visible partially recovered by other objects.

import Tkinter as Tki

#constants - using this you can eventually change the interface's language by importing a different file containning these values.
__title__ = "my first program"
__run__ = "run!"

#widgets contain all the currently created widgets, this will alow to destroy and replace them.
global widgets
widgets = []

#---------------------------------------------------------------------------------------------------
def clean():
    for widget in widgets:
        widget.grid_remove()
        widget.destroy()
#---------------------------------------------------------------------------------------------------
def createMainButton(master):
    clean()
    #it is required to specify the master, i.e. the container of each new widget as first parameter
    button = Tki.Button(root, text = __run__, command = lambda : mainProg(root))
    button.grid(row=0, column=0)
    #have to provide a reference to the widget to allow clean destroy of it.
    widgets.append(button)
#---------------------------------------------------------------------------------------------------
def mainProg(master):
    clean()
    #define a subclass
    def create (content, row, column):
        createLabel(master, content , 20, row , column)
    #create widgets
    create('3', 1, 1)
    create('6', 1, 2)
    create('4', 1, 3)
    create('2', 2, 1)
    create('7', 2, 2)
    create(' ', 2, 3)
    create('5', 3, 1)
    create('1', 3, 2)
    create('8', 3, 3)
#---------------------------------------------------------------------------------------------------

def createLabel(master, content, borderSize, row, column):
    label = Tki.Label(master, text= content, borderwidth=borderSize )
    label.grid(row=row,column=column)
    widgets.append(label)

if __name__ == "__main__":

    root = Tki.Tk()
    root.title(__title__)

    createMainButton(root)  

    root.mainloop()

I don't know what are your knowledge about Object Programming, but consider an other way to achieve your goal : extend the Tk class in order to provide access to required data inside a particular scope without defining global variables ( that is, in general, BAD! ). I personally would code it like this :

import Tkinter as Tki

#constants - using this you can eventually change the interface's language by importing a different file containning these values.
__title__ = "my first program"
__run__ = "run!"

class MyProgram(Tki.Tk):
    def __init__(self):
        Tki.Tk.__init__(self)

        self.widgets = []
        self.CONSTANT_BORDERWIDTH = 20

        self.title(__title__)       
        self.createMainButton()

    def clean(self):
        for widget in self.widgets:
            widget.grid_remove()
            widget.destroy()    

    def createMainButton(self):
        self.clean()
        #it is required to specify the master, i.e. the container of each new widget as first parameter
        button = Tki.Button(self, text = __run__, command = self.mainProg)
        button.grid(row=0, column=0)
        #have to provide a reference to the widget to allow clean destroy of it.
        self.widgets.append(button)

    def mainProg(self):
        self.clean()
        #create widgets
        self.createLabel('3', 1, 1)
        self.createLabel('6', 1, 2)
        self.createLabel('4', 1, 3)
        self.createLabel('2', 2, 1)
        self.createLabel('7', 2, 2)
        self.createLabel(' ', 2, 3)
        self.createLabel('5', 3, 1)
        self.createLabel('1', 3, 2)
        self.createLabel('8', 3, 3)

    def createLabel(self,content, row, column):
        label = Tki.Label(self, text= content, borderwidth=self.CONSTANT_BORDERWIDTH )
        label.grid(row=row,column=column)
        self.widgets.append(label)

if __name__ == "__main__":
    root = MyProgram()
    root.mainloop()

Anyway, if this code is too difficult to understand, forget object programming for now.

Good luck! Arthur.

Arthur Vaïsse
  • 1,551
  • 1
  • 13
  • 26