5
from Tkinter import *

class Window(Tk):
    def __init__(self, parent):
        Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.geometry("600x400+30+30")
        wButton = Button(self, text='text', command = self.OnButtonClick())
        wButton.pack()

    def OnButtonClick(self):
        top = Toplevel()
        top.title("title")
        top.geometry("300x150+30+30")
        topButton = Button(top, text="CLOSE", command = self.destroy)
        topButton.pack()


if __name__ == "__main__":
    window = Window(None)

    window.title("title")

    window.mainloop()

#        top.lift(aboveThis=self)
  #self.configure(state=DISABLED) - unknown option "-state"
  #ss = self.state()
  #self["state"] = "disabled" - unknown option "-state"
#ws = window.state()  # >>> ws outputs: 'normal'
  # varname.unbind("<Button-1>", OnButtonClick)
  #self.unbind("<Button-1>", OnButtonClick)
  #window.unbind("<Button-1>")
###if window.OnButtonClick == True:
###    window.unbind("<Button-1>", OnButtonClick)

The Python ver2.7.3 code above, when ran in IDLE ver2.7.3, using Tkver8.5: displays the smaller top=Toplevel() window first for a second, before displaying one instance of the window=Window(Tk) above it. This is before any buttons are clicked or anything.

All of the comments underneath the above code are just notes to myself of things that I've tried and ideas to try next (idk - maybe unhelpful stuff).

How do I change the above code to: Make the instance of window=Window(Tk) the parent window and the the top=Toplevel() window the child. Then, when I run the program, only the parent window should display; and then when I click on 'wButton', the child window should appear on top of the parent window, with the parent window being disabled - its button inoperable and the user unable to make the window lift to the forefront by clicking on it?

2
  • Please verify the correctness (indentation) of the displayed code. Also, try & keep your question short, but to the point. Commented Nov 24, 2013 at 21:26
  • 1
    The code is now displayed above just as I have it typed in the *.py file. Thanks for fixing my formatting mistake. I guess that some incorrect indentation was messing it up before, because when I put the post in a *.html file, it displayed correctly. I'll abridge the non-code, question part and then edit the post. Commented Nov 25, 2013 at 0:15

2 Answers 2

5

command expects only function name - without () and arguments.

Use

wButton = Button(self, text='text', command = self.OnButtonClick)

If you use command = self.OnButtonClick() you run self.OnButtonClick() and result is assigned to command. It can be very usefull if you want to create function for command dynamicly.


To make child window alway on top parent window you can use child.transient(parent)

In your code it should be top.transient(self)

def OnButtonClick(self):
    top = Toplevel()
    top.title("title")
    top.geometry("300x150+30+30")

    top.transient(self)

    topButton = Button(top, text="CLOSE", command = self.destroy)
    topButton.pack()

You can use .config(state='disabled') and .config(state='normal') to disable/enable button.

You can disable main window button in OnButtonClick() but you need new function to enable that button before/after child window is closed.

from Tkinter import *

class Window(Tk):
    def __init__(self, parent):
        Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.geometry("600x400+30+30")
        self.wButton = Button(self, text='text', command = self.OnButtonClick)
        self.wButton.pack()

    def OnButtonClick(self):
        self.top = Toplevel()
        self.top.title("title")
        self.top.geometry("300x150+30+30")
        self.top.transient(self)
        self.wButton.config(state='disabled')

        self.topButton = Button(self.top, text="CLOSE", command = self.OnChildClose)
        self.topButton.pack()

    def OnChildClose(self):
        self.wButton.config(state='normal')
        self.top.destroy()

if __name__ == "__main__":
    window = Window(None)

    window.title("title")

    window.mainloop()
Sign up to request clarification or add additional context in comments.

Comments

0
Thank you, furas!

"command" expects only a function name - without "()" and arguments. Thanks for catching my error there. I think that's what "mysteriously" changed the results I was getting from before. I made a change to the "command" option, and when I changed it back, I made the mistake of putting in the "()". So, I guess that the result (top already drawn) is what I was getting. That insight about creating functions for "command" dynamically seems very useful indeed. I'm going to keep that one in mind.

Your four suggestions worked great. Ha, I remember trying to figure out how to change the state of a window for a long time, but I could never find any example code, so I did'nt get the syntax correct, even after looking online and at the *.py module with the source code. I'm very appreciative for showing me the solution.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.