Domanda

C'è qualcosa come il pacchetto su nuova linea per TK Geometry Manager?Sto usando il pacco per mettere i widget all'interno di un telaio.Su uno schermo ad alta risoluzione, i widget si adattano a trovare fianco a fianco.Tuttavia, se lo metti in uno schermo più piccolo, i widget finiranno fuori dalla stanza nel telaio.

Fondamentalmente, andiamo da:

PRIMA

A:

dopo

Puoi vedere come si interrompe del mio campo di ingresso dei processori.Il codice pertinente:

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)
.

Un sacco di rilegatura e impostazione degli eventi delle opzioni potrebbe non essere rilevante, ma pensavo che dovrei ancora includere ... solo nel caso.L'opzione migliore sarebbe quella di passare a un gestore di griglia?Il problema ci sarebbe questo telaio è imballato all'interno di un altro ... e così via.Non è che se inizi a utilizzare il Grid Manager, devi usarlo per tutto perché non puoi mescolare il manager confezionato e griglia nella stessa cornice?

È stato utile?

Soluzione

AFAIK Non c'è modo integrato per creare interfacce dinamiche in Tkkinter.La soluzione migliore è ottenere la risoluzione dello schermo e poi la griglia / imballare in modo appropriato.

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

Quindi, ad esempio ....

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)
.

Altri suggerimenti

In generale, sono d'accordo con la risposta di I_do_python, ma farei una piccola modifica. Metterei tutti i widget in un nuovo telaio, e userei la larghezza del telaio come il test di Litmus per passare se avvolgere. E puoi associare un gestore di eventi per l'evento "<Configure>" che controlla se il contenuto del frame deve essere avvolto quando viene ridimensionato la finestra dell'applicazione (e quindi il fotogramma).

Avevo scritto la funzione di seguito che utilizza il metodo della griglia per inserire in modo intelligente i widget in una cornice. Può certamente essere migliorato, ma funziona per me. Di solito se si utilizza .grid() per riempire un genitore, è possibile ottenere spazio bianco sprecato quando i widget di riempimento variano in larghezza. La funzione seguente si rivolge a questo interrompendo il genitore in colonne logiche (divisions nel codice) e consentendo ai widget di estendere più colonne. Il risultato è un layout della griglia con uno spazio bianco sprecato molto ridotto. Più alto si imposta divisions, meglio è il risultato, ma il valore predefinito dovrebbe funzionare per la maggior parte delle situazioni.

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
.

Alla fine prenderò alcuni minuti per riscriverlo con w.winfo_reqwidth() e aggiornerò il mio post.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top