This article builds on the discussion from article 3 and explains how to create and open another Python window.
Frames and Windows
A window in Python is a frame. "Some" frames are also windows. Frames can contain other frames, so not every frame is also a window.
Creating an opening another window is a matter of defining the frame and then executing the code to open it. This article explains one way to accomplish that.
A Second Frame (Window)
The code presented here creates a second frame (Frame2 directly after Frame1 (although Frame1 has many lines of code). This means that Frame2 is defined in the global scope like Frame1. Why is this important (or not)?
Scope refers to where a program variable is defined and exists, and where it doesn't. A variable declared in a class or function only exists in that class and function. In the sample code presented so far for creating a window, a great deal of code has a limited scope of only existing in the Frame1 class. Attempting to reference the UI elements anywhere else will not work. The first label element, labelName is a variable defined inside Frame1. It only exists in Frame1. It cannot be reference in main() or other functions outside of Frame1. labelName is said to be "scoped" to Frame1. All the UI elements in Frame1 are scoped only to that class. They can be referenced in the button functions, because those functions also are scoped to the Frame1 class.
The Frame1 class itself has a global scope (it has no indentation; it is at the same indent level as main()).
Understanding scope is important when planning a modular program. Why?
There is a decision to make when defining another frame. Should it be scoped globally or inside another class or function, such as Frame1? Does it matter?
In this program, Frame2 could be defined inside of Frame1 OR in the global scope. If the ultimate plan was that the window was going the referenced from main() or from other global functions, then it would be necessary to define it in the global scope. For this example, Frame2 is defined inside of Frame1 because it will only be opened from Frame1.
Second Frame Code
The code is basically the same for a second frame as it was for the first frame. In this example, though, the definition for Frame2 is inside the Frame1 class. And the Frame2 class is empty, except for the def __init__ initialization statement. Here is the code:
A new button has been added, named btnNewWindow and the code to prepare and display the second window is all contained within the command function for that button (btnNewWindow_click). It looks similar to how Frame1 is deployed, with a couple of minor change:
- The new frame is specifically defined using the TopLevel() function. This makes sure the frame will be visible as a window.
- The title and geography are defined in a similar fashion as before.
- the .config() method is used to assign a background color("bg") to the frame.
Here is what the main window looks like now:
When the New Window button is clicked, it executes the btnNewWindow_click function, which creates a new instance of Frame2, populates the title, size and color, and creates a label. The window looks like this:
An interesting thing to note about this process: when the new button is clicked and the btnNewWindow_click method is called, it creates a "new" window - every time. Clicking the New Window button multiple times creates multiple instances of Frame2. This may or may not be what is intended. There are ways to detect if a window has been created and to close existing windows,, but those topics are beyond the scope of this article.
Retrieving Text Box Values
You may notice that in the example above for the display of the new window, there are two labels, and the second label contains the value of what was typed in the first text box in the main window. How does that work??
Retrieving the text that was entered in a text box is accomplished by using the .get() method of the text box. In this case, the text box element is named entryName. The command function that is triggered by clicking the New Window button retrieves the value of the textbox and then assigns it to the new label it creates on the new window: