Хобрук: Ваш путь к мастерству в программировании

tkinter — взвешенный холст, не заполняющий пустое пространство

холст занимает весь экран, как видно из зеленого. CanvasFrame имеет две строки, во второй из которых включены виджеты с прокручиваемым текстом. Вторая строка также была взвешена, однако она не заполняет экран, поскольку зеленая область должна быть желтой. Как мне заставить вторую строку заполнить пустое пространство и заставить прокручиваемые текстовые виджеты расширяться по вертикали.

P.S. innerFrame выглядит ненужным в этом примере, но он есть, потому что для простоты я удалил другие виджеты из фрейма.

Холст

код:

import tkinter as tk
from tkinter import ttk
import tkinter.scrolledtext as tks

class Program(tk.Tk):        
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.iconbitmap(self, default = "")
        tk.Tk.wm_title(self, "")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (Page, Other):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.show_frame(Page)

    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()


class Page(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        innerFrame = tk.Frame(self, bg="red")
        innerFrame.place(relx=.5, rely=.5, anchor="c", relwidth=1.0, relheight=1.0)

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

        frameOne = tk.Frame(innerFrame, bg="green")
        frameOne.grid(row=1, sticky="NSWE")

        self.canvas = tk.Canvas(frameOne, bg="green")

        canvasFrame = tk.Frame(self.canvas, bg="yellow")
        canvasFrame.pack()

        canvasFrame.grid_rowconfigure(1, weight=1)

        scrollbar = tk.Scrollbar(frameOne, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=scrollbar.set)
        scrollbar.pack(side="bottom", fill="x")

        self.canvas.pack(fill="both", expand=True)
        self.canvas.create_window((0, 0), window=canvasFrame, anchor="nw")

        for x in range(5):
            pagename = tk.Label(canvasFrame, text = "Unit Name")
            pagename.grid(row=0, column=x, sticky="NSEW")
            text = tks.ScrolledText(canvasFrame, width=50)
            text.grid(row=1, column=x ,sticky="NSEW")

        canvasFrame.bind("<Configure>", self.onFrameConfigure)

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))


class Other(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

app = Program()
app.state('zoomed')
app.mainloop()

  • почему вы используете холст? если все, что у вас есть, это виджеты с возможностью прокрутки, холст не нужен. Или два других кадра, если уж на то пошло. Вы делаете проблему намного сложнее, чем она должна быть. 03.02.2016
  • Мне нужен холст для горизонтальной полосы прокрутки, у меня также есть виджеты за пределами холста, которые идут над и под ним. Горизонтальная полоса прокрутки необходима для прокрутки к виджетам Scrolledtext, которые исчезают с экрана. 03.02.2016

Ответы:


1

У вашего canvasFrame нет причин расширяться, чтобы заполнить холст. Вы поместили в него виджеты, и рамка уменьшится, чтобы соответствовать виджетам.

Наиболее распространенным решением является добавление привязки к событию <Configure> холста, получение высоты холста и использование метода холста itemconfigure для настройки высоты кадра так, чтобы она совпадала с высотой холста.

class Page(...):
    def __init__(...):
        ...
        self.frame_id = self.canvas.create_window(...)
        ...
        self.canvas.bind("<Configure>", self.onCanvasConfigure)

    def onCanvasConfigure(self, event):
        # you might need to subtract a little to account for borders,
        # padding, etc.
        self.canvas.itemconfigure(self.frame_id, height=event.height)
03.02.2016
Новые материалы

Введение в контекст React
В этом посте мы поговорим о Context API, который был представлен в React 16, и о том, как вы можете их использовать. Что такое контекст? Глядя на определение из react docs , оно..

Шлюз с лицензией OSS, совместимый с Apollo Federation v2, появится в WunderGraph
Сегодня мы рады сообщить, что мы сотрудничаем с поддерживаемой YC Tailor Technologies, Inc. для внедрения Apollo Federation v2. Реализация будет лицензирована MIT (Engine) и Apache 2.0..

Это оно
Ну, я официально уволился с работы! На этой неделе я буду лихорадочно выполнять последние требования Думающего , чтобы я мог сосредоточиться на поиске работы. Что именно это значит?..

7 полезных библиотек JavaScript, которые вы должны использовать в своем следующем проекте
Усильте свою разработку JavaScript Есть поговорка «Не нужно изобретать велосипед». Библиотеки — лучший тому пример. Это поможет вам написать сложные и трудоемкие функции простым способом...

Базовое руководство по переносу концепций обучения в глубокое обучение
Обзор По мере того, как машинное обучение становится все более мощным и продвинутым, модели, обеспечивающие эту расширенную возможность, становятся все больше и начинают требовать огромного..

C в C.R.U.D с использованием React-Redux
Если вы использовали React, возможно, вы знакомы с головной болью, связанной с обратным потоком данных. Передача состояния реквизитам от родительских компонентов к дочерним компонентам может..

5 обязательных элементов современного инструмента конвейера данных
В цифровом мире предприятия используют конвейеры данных для перемещения, преобразования и хранения огромных объемов данных. Эти конвейеры составляют основу бизнес-аналитики и играют..