Tkinter - настройка высоты с помощью менеджера сетки - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь создать простое приложение с графическим интерфейсом, используя Tkinter и Python.Приложение должно выглядеть примерно так

------------------------------
Label-1 | Canvas-1
------------------------------
Label-2 | Canvas-2
------------------------------
Label-3 | Canvas-3
------------------------------
 . . .
Label-3 | Canvas-3
------------------------------
        | scrollbar-horizontal
------------------------------

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

Ниже приведен минимальный пример:

import tkinter
import tkinter.font


class LineData(object):

    def __init__(self, desc, box):
        self.desc = desc
        self.box = box

class LinePlotter(object):

    def __init__(self, label, canvas, desc, box):
        self.label = label
        self.canvas = canvas
        self.desc = desc
        self.box = box

    def plot(self):
        self.label.set(self.desc)
        x1, y1 = self.box[0], 1
        x2, y2 = self.box[1], 20
        print(self.desc)
        print(x1, y1, x2, y2)
        print(x2+100, y1, x2+(x2-x1)+100, y2)
        self.canvas.create_rectangle(x1, y1, x2, y2, outline="#D1D0CE", 
                                     width=4, fill="#D1D0CE")

        self.canvas.create_rectangle(x2+100, y1, x2+(x2-x1)+100, y2, outline="#D1D0CE",
                                     width=4, fill="#D1D0CE")


class Plotter(tkinter.Frame):

    def __init__(self, parent, lines_data):
        super().__init__(parent)
        self.parent = parent
        self.lines_data = lines_data

    def set_scroll_bar(self):
        x1, y1, x2, y2 = self.canvases[0].bbox(tkinter.ALL)
        x1 = y1 = 0
        for c in self.canvases:
            t1, u1, t2, u2 = c.bbox(tkinter.ALL)
            x1 = min(x1, t1)
            x2 = max(x2, t2)
            y1 = min(y1, u1)
            y2 = max(y2, u2)

        print("final=", x1, y1, x2, y2)
        for c in self.canvases:
            c.config(scrollregion=(x1-5, y1-5, x2+5, y2+5))

    def xview(self, *args):
        for c in self.canvases:
            c.xview(*args)

    def initUI(self):

        self.scrollX = tkinter.Scrollbar(self, orient=tkinter.HORIZONTAL)

        self.scrollX['command'] = self.xview
        self.scrollX.grid(row=2, column=1, sticky='NSEW')

        self.canvases = []

        h = 10
        for row_idx, line_data in enumerate(self.lines_data):
            desc = tkinter.StringVar()
            font = tkinter.font.Font(size=11)
            label = tkinter.Label(self, textvariable=desc, font=font, 
                                  height=h)
            label.grid(row=row_idx, column=0, sticky=tkinter.W)

            canvas = tkinter.Canvas(self, bg='white', 
                                    xscrollcommand=self.scrollX.set, 
                                    height=h)

            line = LinePlotter(desc, canvas, line_data.desc, line_data.box)
            line.plot()

            canvas.grid(row=row_idx, column=1, sticky=tkinter.W)
            self.canvases.append(canvas)

        self.set_scroll_bar()

        self.pack(expand=True, fill=tkinter.X)


l1 = LineData("L1", (50, 60))
l2 = LineData("L2", (200, 250))

root = tkinter.Tk()

Plotter(root, [l1, l2]).initUI()
root.mainloop()  

Когда я устанавливаю h = None в initUI, я вижу, что объекты расширяются до целогоокно

enter image description here

Когда я устанавливаю h = 10, я вижу, что ряды становятся тоньше, но они распределены по всему экрану.

enter image description here

И когда я устанавливаю h = 50, я вижу только первую строку.

enter image description here

В идеале я хотел бы видеть что-то вроде с h = 10, но один ряд под другим.Как мне этого добиться?

1 Ответ

0 голосов
/ 04 октября 2018

Ваша проблема в том, что h представляет пиксели при создании холста, но количество строк при настройке метки.Используйте его для одного или другого, но не для обоих.

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

Когда я просто удаляю height=h с метки, я получаю следующее:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...