Frage

Gibt es so etwas wie Pack to new line für Tk geometry Manager?Ich verwende pack, um Widgets in einen Rahmen zu setzen.Auf einem hochauflösenden Bildschirm passen die Widgets nebeneinander.Wenn Sie es jedoch auf einem kleineren Bildschirm platzieren, wird den Widgets im Rahmen der Platz ausgehen.

Grundsätzlich gehen wir von:

Before

zu:

after

Sie können sehen, wie es das Eingabefeld meines Prozessors abschneidet.Der relevante Code:

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)

Ein Großteil der Ereignisbindung und Einstellung der Optionen ist möglicherweise nicht relevant, aber ich dachte, ich sollte sie trotzdem einbeziehen...nur für den Fall.Wäre die beste Option, zu einem Netzmanager zu wechseln?Das Problem dort wäre, dass dieser Rahmen in einen anderen gepackt ist...und so weiter.Ist es nicht so, dass Sie den Grid Manager, wenn Sie ihn verwenden, für alles verwenden müssen, weil Sie Packed und Grid Manager nicht im selben Frame mischen können?

War es hilfreich?

Lösung

afaik Es gibt keine eingebaute Möglichkeit, dynamische Schnittstellen in Tkinter zu erstellen.Ihre beste Wette besteht darin, die Bildschirmauflösung zu erhalten, und dann angemessen Raster / Packung.

generasacodicetagpre.

so zum Beispiel ....

generasacodicetagpre.

Andere Tipps

Im Allgemeinen stimme ich der Antwort von I_do_python zu, aber ich würde eine kleine Änderung vornehmen.Ich würde alle Widgets in einen neuen Rahmen einfügen und die Breite des Rahmens als Lackmustest verwenden, ob er umgebrochen werden soll.Und Sie können einen Ereignishandler für die binden "<Configure>" ereignis, das dann überprüft, ob der Inhalt des Rahmens umgebrochen werden muss, wenn die Größe des Anwendungsfensters (und damit des Rahmens) geändert wird.

Ich hatte die folgende Funktion geschrieben, die die Rastermethode verwendet, um Widgets intelligent in einen Frame einzufügen.Es kann sicherlich verbessert werden, aber es funktioniert für mich.Normalerweise, wenn Sie verwenden .grid() um ein übergeordnetes Element zu füllen, können Sie Leerraum verschwenden, wenn die Breite der Füll-Widgets variiert.Die folgende Funktion behebt dies, indem sie das übergeordnete Element in logische Spalten aufteilt (divisions im Code) und Zulassen, dass sich die Widgets über mehrere Spalten erstrecken.Das Ergebnis ist ein Rasterlayout mit stark reduziertem verschwendetem Leerraum.Je höher Sie einstellen divisions, desto besser das Ergebnis, aber der Standardwert sollte für die meisten Situationen funktionieren.

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

Irgendwann werde ich mir ein paar Minuten Zeit nehmen, um es neu zu schreiben w.winfo_reqwidth() und werde meinen Beitrag aktualisieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top