Pregunta

Hay algo como paquete a la nueva línea de los conocimientos tradicionales de geometría manager?Estoy utilizando el paquete para poner widgets dentro de un marco.En una pantalla de alta resolución, los widgets ajuste encuentran lado a lado.Sin embargo, si la pones en una pantalla más pequeña, los widgets se quede sin espacio en el marco.

Básicamente, vamos a partir de:

Before

a:

after

Usted puede ver cómo se corta de mi Procesadores campo de entrada.El código correspondiente:

options_frame = ttk.LabelFrame(
        parent_frame, text="Blast Options")
options_frame.pack(side=TOP, fill=X, expand=1, padx=5, pady=5)
        self._set_up_blast_options(options_frame)

def _set_up_blast_options(self, options_frame):
    self.evalue = Tkinter.DoubleVar()
    self.evalue.set(1)
    self.word_size = Tkinter.IntVar()
    self.word_size.set(4)
    self.penalty_mismatch = Tkinter.DoubleVar()
    self.penalty_mismatch.set(-4)
    self.min_d_match = Tkinter.IntVar()
    self.min_d_match.set(5)
    self.proc_count = Tkinter.IntVar()
    self.proc_count.set(cpu_count())

    # evalue
    e_value_label = ttk.LabelFrame(
        options_frame, text="e-Value Threshold")
    e_value_entry = ttk.Entry(e_value_label)
    e_value_entry.insert(0, self.evalue.get())
    e_value_entry.bind('<Return>', self._validate_e_value)
    e_value_entry.bind('<FocusOut>', self._validate_e_value)
    e_value_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    e_value_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    # word size
    word_size_label = ttk.LabelFrame(
        options_frame, text="Word Size")
    word_size_entry = ttk.Entry(word_size_label)
    word_size_entry.insert(0, self.word_size.get())
    word_size_entry.bind('<Return>', self._validate_word_value)
    word_size_entry.bind('<FocusOut>', self._validate_word_value)
    word_size_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    word_size_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    penalty_mismatch_label = ttk.LabelFrame(
        options_frame, text="Penalty Mismatch")
    penalty_mismatch_entry = ttk.Entry(penalty_mismatch_label)
    penalty_mismatch_entry.insert(0, self.penalty_mismatch.get())
    penalty_mismatch_entry.bind(
        '<Return>', self._validate_penalty_mismatch_value)
    penalty_mismatch_entry.bind(
        '<FocusOut>', self._validate_penalty_mismatch_value)
    penalty_mismatch_label.pack(side=LEFT, expand=1, pady=5,
                                padx=5, fill=X)
    penalty_mismatch_entry.pack(side=TOP, expand=1, pady=5,
                                padx=5, fill=X)
    # Min D Nucleotides
    min_d_match_label = ttk.LabelFrame(
        options_frame, text="Minimal Number of D Nucleotides")
    min_d_match_entry = ttk.Entry(min_d_match_label)
    min_d_match_entry.insert(0, self.min_d_match.get())
    min_d_match_entry.bind(
        '<Return>', self._validate_min_match_value)
    min_d_match_entry.bind(
        '<FocusOut>', self._validate_min_match_value)
    min_d_match_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    min_d_match_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

    # how many cpus to use
    proc_count_label = ttk.LabelFrame(
        options_frame, text="Processors")
    proc_count_entry = ttk.Entry(proc_count_label)
    proc_count_entry.insert(0, self.proc_count.get())
    proc_count_entry.bind(
        '<Return>', self._validate_proc_count_value)
    proc_count_entry.bind(
        '<FocusOut>', self._validate_proc_count_value)
    proc_count_label.pack(side=LEFT, expand=1, pady=5, padx=5, fill=X)
    proc_count_entry.pack(side=TOP, expand=1, pady=5, padx=5, fill=X)

Muchos de los eventos de enlace y la configuración de las opciones puede no ser relevante, pero pensé que debía incluir...por si acaso.Sería la mejor opción para cambiar a un grid manager?El problema no sería que este marco es empaquetado dentro de la otra...y así sucesivamente.No es que si empiezas a usar gestor de la red, usted tiene que usarlo para todo, porque no se puede mezclar embalados y grid manager en el mismo cuadro?

¿Fue útil?

Solución

afaik No existe una forma incorporada de crear interfaces dinámicas en Tkinter.Su mejor apuesta es obtener la resolución de la pantalla y luego la cuadrícula / Paquete adecuadamente.

user32 = ctypes.windll.user32
get_screensize = (user32.GetSystemMetrics(0), user32.GetSystemMetrics(1))

así, por ejemplo ...

widget1 = tkinter.Entry(root,width=20,etc)
widget2 = tkinter.Label(root,text='Hello',etc)
## Now perform update_idletasks() which will force
## Tkinter to calculate their size.
widget1.update_idletasks()
widget2.update_idletasks()
## Now calculate whether they'll fit.
if widget1.winfo_width() + widget2.winfo_width() > screensize[0]:## Not enough space
    widget1.grid(row=0)
    widget2.grid(row=1)
else:## Both will fit on one line.
    widget1.grid(row=0,column=0)
    widget2.grid(row=0,column=1)

Otros consejos

En general, estoy de acuerdo con I_do_python la respuesta, pero me gustaría hacer una pequeña modificación.Me gustaría poner todos los widgets en un nuevo Marco, y me gustaría utilizar el Marco de la anchura como la prueba de fuego en cuanto a si para envolver.Y puede enlazar un controlador de eventos para el "<Configure>" caso de que, a continuación, comprueba para ver si el Marco de los contenidos de la necesidad de estar envuelto en cuando la ventana de la aplicación (y por lo tanto la Trama) se cambia el tamaño.

Yo había escrito la siguiente función que utiliza el método de red de forma inteligente insertar widgets en un marco.Sin duda se puede mejorar, pero a mí me funciona.Por lo general, si usted utiliza .grid() para llenar un padre, usted puede echar a perder el espacio en blanco cuando el relleno widgets varían en anchura.La siguiente función de las direcciones de este mediante la ruptura de los padres en la lógica de las columnas (divisions en el código), y permitiendo que los widgets para abarcar varias columnas.El resultado es un diseño de cuadrícula con mucho-reducción del desperdicio de espacio en blanco.El más alto es divisions, mejor será el resultado, pero el valor por defecto debería funcionar para la mayoría de las situaciones.

def smart_grid(parent, *args, **kwargs): # *args are the widgets!
    divisions   = kwargs.pop('divisions', 100)
    force_f     = kwargs.pop('force', False)
    if 'sticky' not in kwargs:
        kwargs.update(sticky='w')
    try:
        parent.win_width
    except:
        parent.win_width = -1
    winfo_width = parent.winfo_width()
    if 1 < winfo_width != parent.win_width or force_f:
        parent.win_width = winfo_width
        row = col = width = 0
        argc = len(args)
        for i in range(argc):
            widget_width = args[i].winfo_width()
            columns = max(1, int(widget_width * float(divisions) / winfo_width))
            width += widget_width
            if width > winfo_width:
                width = widget_width
                row += 1
                col = 0
            args[i].grid(row=row, column=col, columnspan=columns, **kwargs)
            col += columns
        parent.update_idletasks() # update() # 
        return row + 1

Con el tiempo me va a tomar unos minutos para volver a escribir con w.winfo_reqwidth() y actualizar mi post.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top