如何在Tkinter的Toplevel窗口强制调整大小?

时间:2016-02-07 13:36:52

标签: python python-2.7 tkinter

我与Tkinter的冒险继续。 这是一个试用的演示代码:

#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import threading as thr
import ttk
import Tkinter as tk
import Queue

import loop_file


class MyApp(ttk.Frame):
    def __init__(self, master):
        ttk.Frame.__init__(self, master)
        self.grid()
        self.model_queue = Queue.PriorityQueue()
        self.butt = ttk.Button(self, text='Click me!', command=self.proc)
        self.butt.grid()

    def finish_loop_window(self):
        # remove "Wait" message
        self.waitFr.destroy()
        # create Frames for Toplevel window
        graphFr = ttk.Frame(self.loop_win, borderwidth=2, relief='groove')
        graphFr.grid(row=0, column=0, sticky='nsew')

        # update to get the new dimensions
        self.update()
        self.loop_win.update()
        newsize = self.loop_win.winfo_geometry()
        print newsize
        ttk.Label(self.loop_win, text=self.fib_result).grid()
        self.loop_win.geometry(newsize)  # here I expected the window to be resized


    def check_looping_thread_save_results(self):
        """
        Check every 10ms if loop thread is alive.
        """
        if self.loop_thread.is_alive():
            self.after(10, self.check_looping_thread_save_results)
        else:
            self.loop_thread.join()
            # get the results of model processing
            self.fib_result = self.model_queue.get()
            self.finish_loop_window()

    def centrify_widget(self, widget):
        widget.update_idletasks()
        width = widget.winfo_screenwidth()
        height = widget.winfo_screenheight()
        xy = tuple(int(c) for c in widget.geometry().split('+')[0].split('x'))
        xpos = width/2 - xy[0]/2
        ypos = height/2 - xy[1]/2
        widget.geometry("%dx%d+%d+%d" % (xy + (xpos, ypos)))

    def proc(self):
        self.model_queue = Queue.PriorityQueue()
        self.loop_thread = thr.Thread(target=loop_file.do_looping,
                                        args=(self.model_queue, ))
        self.loop_thread.start()
        self.after(10, self.check_looping_thread_save_results)

        self.loop_win = tk.Toplevel()
        self.loop_win.title('Toplevel')
        self.waitFr = ttk.Frame(self.loop_win, borderwidth=2, relief='groove')
        self.waitFr.grid(sticky='nsew')
        ttk.Label(self.waitFr, text='Wait...\nCreating plots...').grid()
        self.centrify_widget(self.loop_win)


root = tk.Tk()
root.title('Test')
root.update()
gui = MyApp(root)
gui.mainloop()

外部loop_file

#!/usr/bin/python2.7
# -*- coding: utf-8 -*-


def run_fib(n):
    if n == 1:
        return 1
    elif n == 0:
        return 0
    else:
        return run_fib(n-1) + run_fib(n-2)

def do_looping(queue):
    answer = run_fib(35)
    queue.put(answer)

如果您运行此小型演示,则会看到Click me!按钮。如果单击它,将出现一个弹出窗口Wait... Creating plots...,并将运行一个单独的线程。线程完成后,窗口会更新,但未调整大小

enter image description here enter image description here enter image description here

如何在更新后调整窗口大小?

1 个答案:

答案 0 :(得分:2)

如果我正确理解了问题,您需要缩小弹出窗口以适应新内容。

如果是这种情况,除了删除之前放在窗口上的尺寸限制外,您不必做任何事情。当您使用参数调用geometry时,这将覆盖在该窗口中可能发生的任何自然重新调整大小。你问它是一个特定的大小,所以tkinter努力兑现这个愿望。

如果将空字符串传递给geometry,tkinter将删除该约束并让窗口增大或缩小以适合其内容。

试试这个:

def finish_loop_window(self):
    # remove "Wait" message
    self.waitFr.destroy()

    # remove the fixed size of the window that was previously applied
    self.loop_win.geometry("")

    # create Frames for Toplevel window
    graphFr = ttk.Frame(self.loop_win, borderwidth=2, relief='groove')
    graphFr.grid(row=0, column=0, sticky='nsew')
    ttk.Label(self.loop_win, text=self.fib_result).grid()