В Python tkinter команда yscroll текстового виджета не работает должным образом - PullRequest
0 голосов
/ 24 января 2019

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

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

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

f/l:  0.0 0.9732142857142857
---
f/l:  0.026785714285714284 1.0
---
f/l:  0.0 0.9732142857142857
---
f/l:  0.026785714285714284 1.0
---
f/l:  0.0 0.9732142857142857
---
f/l:  0.026785714285714284 1.0
---
f/l:  0.0 0.9732142857142857
---
f/l:  0.026785714285714284 1.0

Вот соответствующий код:

from tkinter import *
from tkinter.ttk import *


class MyApp(Frame):
  def __init__(self, parent, *args, **kwargs):
    Frame.__init__(self, parent)
    self.pack()
    self.parent = parent

    self.action_frame = Frame(self, name="action")
    self.vis_frame = Panedwindow(self.action_frame, orient=HORIZONTAL)
    self.action_frame.pack(fill=BOTH, expand=YES)
    self.vis_frame.pack(fill=BOTH, expand=YES)

    fr = LabelFrame(self.vis_frame, text="Comments")
    fr1 = LabelFrame(self.vis_frame, text="Draft")

    self.text = Text(fr)
    self.lbl_fr = Text(fr, width=4, state=DISABLED, background="SystemMenu")
    self.scrl = Scrollbar(fr, orient=VERTICAL)

    Button(fr, text="Submit", command=self.submit).pack(side=BOTTOM)
    self.scrl.pack(side=RIGHT, fill=Y)
    self.text.pack(side=RIGHT, fill=BOTH)
    self.lbl_fr.pack(side=RIGHT, fill=Y)

    self.scrl.configure(command=self.__scrollBoth)
    self.text.configure(yscrollcommand=self.__updateScroll)
    self.lbl_fr.configure(yscrollcommand=self.__updateScroll)

    self.vis_frame.add(fr1, weight=1)
    self.vis_frame.add(fr)

    bindtags = list(self.text.bindtags())
    bindtags.insert(2, "custom")
    self.text.bindtags(tuple(bindtags))

    self.text.bind_class("custom", "<Return>", self.lbls)
    self.text.bind_class("custom", "<Key>", self.lbls)
    self.text.bind_class("custom", "<BackSpace>", self.lbls)
    self.text.bind_class("custom", "<Delete>", self.lbls)

    self.cur = self.lbl_fr.index(INSERT)

  def lbls(self, e=None):

    self.text.see("{}+1c".format(INSERT))

    self.lbl_fr["state"] = NORMAL
    self.lbl_fr.delete("0.0", END)
    i = "1.0"
    while True:
        if i == self.text.index(END):
            break

        linenum = str(i).split(".")[0]

        if i[:-2] == self.text.index(INSERT).split(".")[0]:
            self.cur = self.lbl_fr.index(INSERT)
        what = "{}.\n".format(linenum)
        self.lbl_fr.insert(INSERT, what)
        for j in range(len(self.text.get(i, i+"+1l-1c"))//self.text.cget("width")):
            if i[:-2] == self.text.index(INSERT).split(".")[0]:
                if j+1 == int(self.text.index(INSERT).split(".")[1]) // self.text.cget("width"):
                    self.cur = self.lbl_fr.index(INSERT)
            self.lbl_fr.insert(INSERT, " \n")

        i = self.text.index("{}+1l".format(i))

    self.lbl_fr.delete(INSERT+"-1c", INSERT+" lineend")
    self.lbl_fr["state"] = DISABLED
    print("---------------------------")
    # print("--->", self.cur)

  def __scrollBoth(self, act, pos, type=None):
    self.text.yview_moveto(pos)
    self.lbl_fr.yview_moveto(pos)
    print("pos: ", pos)

  def __updateScroll(self, first, last, type=None):
    self.text.yview_moveto(first)
    self.lbl_fr.yview_moveto(first)
    self.scrl.set(first, last)
    # self.text.see(INSERT)
    # self.lbl_fr.see(self.cur)
    print("f/l: ", first, last)

  def submit(self):
    pass


if __name__ == "__main__":
   root = Tk()
   MyApp(root)
   root.mainloop()

Кто-нибудь сталкивался с какой-либо подобной проблемой или мог понять, почему это происходит?Я попробовал обходной путь, добавив две прокомментированные строки в методе __ updateScroll , чтобы явно разместить оба виджета там, где есть INSERT (переменная self.cur равнавсегда обновляется с соответствующей позицией метки INSERT в текстовом виджете lbl_fr * ), но, конечно, это не идеальное решение, так как оно не работает должным образом при прокруткевиджет без изменения INSERT .

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