There are usually two solutions to this problem. None of them are better than others under any circumstances or in this particular example. Both solutions are perfectly acceptable.
Solution 1: use two containers (usually frames). One for storing horizontal items, one for storing vertical items. In this case, the root window can serve as a container for elements with vertical stacking. Place the two buttons in a horizontal frame (using the package (side = LEFT)), then place this frame above the text widgets (using the package (side = TOP)).
Solution 2: Use the grid geometry manager, which defines your user interface in the grid. Place the buttons in cells 0.1 and 0.2, and the text widget in 1.1, spanning two columns.
Typically, using a grid requires more careful planning. You need to figure out which elements should cover the columns or rows, which columns or rows should grow and decrease as the widget resizes, etc. The batch solution is the “easiest” (for some definitions “easy”, anyway) for very simple layouts like this.
A general method of using frames to place widget groups is a good one. This makes it easy to manage entire sets of widgets as a group. and mix and match left-right widget groups and top widget groups.
Here's how I would do it using a multi-frame technique. Notice how I create widgets as children of root, not as children of internal frames. This makes it a little easier to change the layout in the future, since all you have to do is create or delete different frames without changing the hierarchy of widgets.
The following is a naive implementation using a grid. It has another size change, which may or may not be what you want. It really depends on the resizing behavior you desire. Usually I control a string of controls with a frame, and then use the grid to lay it out along with other widgets. In this example, I just use the grid for everything.
Please note that in addition to managing the rows and columns (s) in which the widget is located, you need to determine the weighting factor for the rows and columns. At a minimum, you need to select one row and one column in order to “pick up a slack”, which usually means any column that contains your main widget (read: usually text, canvas or another frame).
b = Button(root, text="Enter", width=10, height=2, command=button1) c = Button(root, text="Clear", width=10, height=2, command=clear) b.grid(row=0,column=0, sticky=W) c.grid(row=0,column=1, sticky=W) textframe = Frame(root) textframe.grid(in_=root, row=1, column=0, columnspan=3, sticky=NSEW) root.columnconfigure(0, weight=1) root.rowconfigure(1, weight=1) text = Text(root, width=35, height=15) scrollbar = Scrollbar(root) scrollbar.config(command=text.yview) text.config(yscrollcommand=scrollbar.set) scrollbar.pack(in_=textframe, side=RIGHT, fill=Y) text.pack(in_=textframe, side=LEFT, fill=BOTH, expand=True)
In this particular case, I would choose the first method, one with the package. For more complex designs, I almost always use a mixture of both mesh and packaging. Use the package for items that naturally stack either horizontally or vertically (for example, toolbars). Use the grid for more complex layouts (for example, the entire application, widgets with scroll bars, dialogs, etc.). You cannot use both the grid and the package for the same container, but you can use the package for one container, the mesh for another, etc.