LetMeSOThat4U
LetMeSOThat4U

Reputation: 6758

Resizing a Listbox in Python Tk app

I have this:

#!/usr/bin/env python

import Tkinter
import ttk
import datetime

from Tkinter import Tk, Frame, Entry, Button, Listbox, N, S, E, W

class TkPersonalActivityLog(object):

    def __init__(self):
        pass

    def configure_window(self, root):

        root.grid_columnconfigure(0, weight=1)
        root.grid_rowconfigure(0, weight=1)
        root.grid_rowconfigure(1, weight=1)
        root.grid_rowconfigure(2, weight=2)

        self.frame = Frame(root)
        self.frame.grid(sticky=N+E+S+W)
        self.frame.grid_columnconfigure(0, weight=2)
        self.frame.grid_rowconfigure(0, weight=2)
        self.frame.grid_rowconfigure(1, weight=2)
        self.frame.grid_rowconfigure(2, weight=2)

        self.entry = Entry(self.frame, bg='#e3ecfc')
        self.entry.grid(row=0, sticky=E+W)
        self.entry.focus_set()

        self.savebutton = Button(self.frame, text="Save and Minimize", fg="Black", command=self.cb_save_button)
        self.savebutton.grid(row=1)

        self.history = Listbox(self.frame)
        self.history.grid(row=2,sticky=N+S+E+W)

    def cb_save_button(self):
        act = (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), self.entry.get())
        self.history.insert(0, ' '.join(act))

    def mainloop(self):
        self.root = Tk()
        self.configure_window(self.root)
        self.root.mainloop()


if __name__ == '__main__':
    main = TkPersonalActivityLog()
    main.mainloop()

I want self.history to resize to the bottom of the window on resizing the entire window. As it is, it's not doing that:

enter image description here

That is, it does resize horizontally to the sides of the main window as I want it, but it does not resize vertically to the bottom of the window.

Why is that? After all, I do tell it to be sticky=N+S+E+W?

Upvotes: 1

Views: 191

Answers (1)

Mike - SMT
Mike - SMT

Reputation: 15226

You could save your self some headache if you just import Tkinter as tk.

Try changing this:

from Tkinter import Tk, Frame, Entry, Button, Listbox, N, S, E, W

To:

Import Tkinter as Tk

Also you do not need to import N, S, E, W as you can use a string for those direction. So sticky = "nsew" works just as well as sticky = N+S+E+W Your main issue is not the listbox not filling the frame but rather your self.frame not filling the root window.

First lets remove all the useless weights. Because your self.frame is only being placed on row=0, column=0 and you have no other widgets placed in the root window there is no need to provide weights to other rows/columns.

Change this:

root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_rowconfigure(2, weight=2)

To:

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

Then lets change the weights of the Frame so that the list box expands.

Change:

self.frame.grid_columnconfigure(0, weight=2)
self.frame.grid_rowconfigure(0, weight=2)
self.frame.grid_rowconfigure(1, weight=2)
self.frame.grid_rowconfigure(2, weight=2)

To:

self.frame.grid_columnconfigure(0, weight=1)
self.frame.grid_rowconfigure(2, weight=1)

This should fix your resizing problem.

Results:

enter image description here

On a different note you are importing methods from tkinter more than once. This should be avoided and is not needed. Here is a modified version of your code that I think is a bit cleaner and requires less lines to complete the same task.

#!/usr/bin/env python

import Tkinter as tk
import datetime

class TkPersonalActivityLog(object):

    def __init__(self, root):
        self.master = root
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)

        self.frame = tk.Frame(self.master)
        self.frame.grid(sticky="nsew")
        self.frame.grid_columnconfigure(0, weight=1)
        self.frame.grid_rowconfigure(2, weight=1)

        self.entry = tk.Entry(self.frame, bg='#e3ecfc')
        self.entry.grid(row=0, sticky="ew")
        self.entry.focus_set()

        self.savebutton = tk.Button(self.frame, text="Save and Minimize", fg="Black", command=self.cb_save_button)
        self.savebutton.grid(row=1)

        self.history = tk.Listbox(self.frame)
        self.history.grid(row=2,sticky="nsew")

    def cb_save_button(self):
        act = (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), self.entry.get())
        self.history.insert(0, ' '.join(act))


if __name__ == '__main__':
    root = tk.Tk()
    main = TkPersonalActivityLog(root)
    root.mainloop()

This code is shorter and prevents multiple imports by using import Tkinter as Tk.

Upvotes: 2

Related Questions