Вертикальные и горизонтальные полосы прокрутки на виджете Tkinter - PullRequest
7 голосов
/ 05 марта 2012

Я пытаюсь вывести содержимое базы данных в виджет Tkinter. В базе данных достаточно строк и столбцов, где мне нужно включить горизонтальную и вертикальную полосы прокрутки, но мне трудно заставить горизонтальную и вертикальную прокрутку работать одновременно. Я не знаю, какой виджет Tkinter используется, но вот моя текущая реализация:

# Create root
self.root = Tk()
self.root.geometry('1000x500+0+0')

# Create canvas
self.canvas = Canvas(self.root)
self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE)

# Create scrollbars
self.xscrollbar = Scrollbar(self.root, orient=HORIZONTAL, command=self.canvas.xview)
self.xscrollbar.pack(side=BOTTOM, fill=X)
self.yscrollbar = Scrollbar(self.root, orient=VERTICAL, command=self.canvas.yview)
self.yscrollbar.pack(side=RIGHT, fill=Y)

# Attach canvas to scrollbars
self.canvas.configure(xscrollcommand=self.xscrollbar.set)
self.canvas.configure(yscrollcommand=self.yscrollbar.set)

# Create frame inside canvas
self.frame = Frame(self.canvas)
self.canvas.create_window((0,0), window=self.frame, anchor=NW)
self.frame.bind('<Configure>', self.set_scrollregion)

# Write db contents to canvas
self.print_dbcontents()

# Invoke main loop
self.root.mainloop()

def set_scrollregion(self, event):
    self.canvas.configure(scrollregion=self.canvas.bbox('all'))

В этой реализации прокрутка может работать только в одном направлении, в зависимости от способа упаковки холста:

self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE) # scrolling works in x but not y
self.canvas.pack(side=LEFT, fill=BOTH, expand=TRUE) # scrolling works in y but not x

Мне просто нужно заставить горизонтальную и вертикальную прокрутку работать одновременно или найти альтернативное решение.

1 Ответ

9 голосов
/ 05 марта 2012

Я не вижу кода, который бы мешал работе полос прокрутки.Я вижу проблему, которая препятствует тому, чтобы одна из полос прокрутки показывала, где Вы ожидаете это (предполагая, что Вы ожидаете, что они появятся в традиционном месте).Это то, что вы имеете в виду, когда говорите, что хотите, чтобы они «работали одновременно»?

Ваш макет выполнен с использованием следующего кода и в следующем порядке:

self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE)
self.xscrollbar.pack(side=BOTTOM, fill=X)
self.yscrollbar.pack(side=RIGHT, fill=Y)

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

Быстрое решение - сначала упаковать вертикальную полосу прокрутки, затем горизонтальную, и , а затем холст.Ваш "главный" виджет всегда должен быть одним из последних, что вы упаковываете / сетку.Во-первых, вы делаете это по очевидной причине, которая вам необходима в этом случае, чтобы получить желаемый эффект, но также потому, что это делает ваше поведение по изменению размера правильным.Я не в теме, чтобы объяснить, почему в этом ответе, поэтому прочитайте этот ответ для stackoverflow для получения дополнительной информации.

Во-вторых, при работе с полосами прокрутки лучше использовать grid, если вы хотитепрофессиональная внешность.Если вы используете пакет, полосы прокрутки не будут выравнивать свойство в углу, в котором они встречаются.Вы хотите, чтобы они выглядели так, с небольшим пустым пространством в правом нижнем углу:

  ||
==

Однако, если вы используете пакет, они будут выглядеть так:

   ||    -or-      ||
 ====            ==||

Наконец, я призываю вас не import *, это может вызвать проблемы в будущем.Вместо этого возьмите в привычку делать import Tkinter as tk, а затем ставить перед всеми командами tk префикс «tk».(например: tk.Canvas и т. д.).Вы поймете, почему это важно, когда вы впервые попытаетесь смешать виджеты ttk и tkinter в одном и том же интерфейсе, но у вас могут возникнуть проблемы в другом месте, если вы также «импортируете *» из других пакетов.Кроме того, этот способ очевиден, когда вы используете функции tk и когда вы используете функции из других пакетов.

...