Python tkinter,使两个文本小部件的滚动同步 [英] Python tkinter, Making two text widget's scrolling synchronize

查看:96
本文介绍了Python tkinter,使两个文本小部件的滚动同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使两个文本小部件的滚动同步.到目前为止,我已经使用滚动条实现了这一点,使用滚动条时它工作正常.但是,例如,当我将焦点放在一个文本小部件上并使用鼠标滚轮滚动时,只有具有焦点的文本小部件会滚动,滚动条也会更新,但其他文本保持不变.使用向下翻页或向上翻页键时会发生相同的行为,正如我所知,对于不使用滚动条的每种滚动形式.

I am trying to make two text widget's scrolling synchronize. So far I've achieved that using an Scrollbar, when using the scrollbar it works fine. But for example, when I have the focus on one of the text widgets and I use the mousewheel to scroll, only the text widget with the focus is scrolled, the scrollbar is also updated but the other text remains the same. The same behaviour occurs when using page down or page up keys and as fas as I know for every form of scrolling that doesn't use the scrollbar.

这是我的代码,我认为只有 init 是我绑定事件的相关部分,但以防万一我决定把我所有的代码:

This is my code, I think only init is the relevant part where I bind the events, but just in case I decided to put all my code:

## HexText class
#
#
class HexText (tkk.Frame):

    __POS_TEXT = "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"
    __OFFSET_TEXT = "0x00000000"
    __LINE_LENGTH = len(__POS_TEXT)

    def __init__(self, master):

        super(HexText, self).__init__(master)

        self.__create_widgets()
        self.__organize_widgets()

    def __scrolls(self, *args):
        self.__data.yview(*args)
        self.__offset.yview(*args)

    def __create_widgets(self):

        self.__scrollbar = tkk.Scrollbar(self)
        self.__scrollbar["orient"] = tk.VERTICAL
        self.__scrollbar["command"] = self.__scrolls

        self.__data = tk.Text(self)
        self.__data["height"] = 8
        self.__data["width"] = HexText.__LINE_LENGTH
        self.__data["state"] = tk.DISABLED
        self.__data["relief"] = tk.GROOVE
        self.__data["yscrollcommand"] = self.__scrollbar.set

        self.__offset = tk.Text(self)
        self.__offset["height"] = 8
        self.__offset["width"] = len(HexText.__OFFSET_TEXT)
        self.__offset["state"] = tk.DISABLED
        self.__offset["relief"] = tk.FLAT
        self.__offset["bg"] = self.winfo_toplevel()["bg"]
        self.__offset["yscrollcommand"] = self.__scrollbar.set

        self.__pos = tk.Text(self)
        self.__pos.insert(tk.CURRENT, HexText.__POS_TEXT)
        self.__pos["height"] = 1
        self.__pos["width"] = HexText.__LINE_LENGTH
        self.__pos["state"] = tk.DISABLED
        self.__pos["relief"] = tk.FLAT
        self.__pos["bg"] = self.winfo_toplevel()["bg"]

    def __organize_widgets(self):

        self.__pos.grid(row = 0, column = 1, sticky = tk.N + tk.E + tk.W + tk.S)
        self.__offset.grid(row = 1, column = 0, sticky = tk.N + tk.E + tk.W + tk.S)
        self.__data.grid(row = 1, column = 1, sticky = tk.N + tk.E + tk.W + tk.S)
        self.__scrollbar.grid(row = 1, column = 2, sticky = tk.N + tk.E + tk.W + tk.S)

    @staticmethod
    def __get_char_index(string):
        i = str.find(string, '.')

        if i >= 0:
            i = int(string[i+1:])
        else:
            raise ValueError

        return i

    @staticmethod
    def __get_line_index(string):
        i = str.find(string, '.')

        if i >= 0:
            i = int(string[:i])
        else:
            raise ValueError

        return i

    @staticmethod
    def __get_hex_value(string):

        if (len(string) != 1):
            raise ValueError

        i = "%02X" % ord(string)

        return i

    def __update_offset(self, line_index):

        i = "0x%08X\n" % ((line_index) * 0x10)
        self.__offset["state"] = tk.NORMAL
        self.__offset.insert(tk.CURRENT, i)
        self.__offset["state"] = tk.DISABLED

    def __append(self, string):
        self.__data["state"] = tk.NORMAL
        self.__data.insert(tk.CURRENT, string)
        self.__data["state"] = tk.DISABLED

    def __write_char(self, string):
        str_index = self.__data.index(tk.CURRENT)
        i = HexText.__get_char_index(str_index)

        if (len(string) != 1):
            raise ValueError

        if (i == 0):
            self.__update_offset(HexText.__get_line_index(str_index) - 1)

        if (i == HexText.__LINE_LENGTH - 2):
            self.__append(HexText.__get_hex_value(string) + '\n')
        else:
            self.__append(HexText.__get_hex_value(string) + ' ')

    def write_str(self, string):

        for chars in string:
            self.__write_char(chars)

这是我正在尝试创建的小部件的图像,一个简单的十六进制查看器(两个文本小部件的行数相同):

This is an image of the widget I'm trying to create, a simple hex viewer (both text widgets have the same amount of lines):

http://i.stack.imgur.com/Yb8IH.png

所以我的问题是,我应该独立处理所有向上翻页、向下翻页、鼠标滚轮和其他所有滚动形式吗?难道没有更简单的方法让两个文本小部件始终具有相同的滚动效果吗?

So my question is, should I handle all the page up, page down, mousewheel and every other form of scrolling independently? Isn't there a more simple way of having both text widgets have the same scrolling all the time?

推荐答案

回答您的问题是否应该为每个滚动条独立完成事件处理 - 这是您必须做出的决定.如果您只想为此目的制作此小部件,则可以将两者一起处理,而不是单独处理.为此创建一个自定义事件处理程序并相应地调用 setter/getter.

To answer your question if the event handling should be done independently for each scrollbar - that is a decision you have to make. If you want to only make this widget for this purpose, you can handle both together not on their own. Create a custom event handler for that and call the setters/getters accordingly.

如果您有两个小部件(包括两个滚动条)在要绑定事件的主小部件中,请使用widget.bind(<EVENT>, handler) 或使用 widget.bind_all(<EVENT>, handler) 也将从子部件引发的事件绑定到这些处理程序.

If you have the two widgets (including the two scrollbars) are in a main widget where you want to have the events bound, bind them over there using widget.bind(<EVENT>, handler)or using widget.bind_all(<EVENT>, handler) to bind also the events raised from child widgets to these handlers.

由于您已经在代码中使用了相同的处理程序 (self.__scrollbar.set),您可以只使用自定义事件处理程序来绑定 Page Up/Page Down 键按特定偏移量滚动,还有一个自定义按 MouseWheel- 事件滚动.

As you are already using the same handler (self.__scrollbar.set) in your code, you could just use a custom event handler to bind Page Up / Page Down keys to scroll by a specific offset, and one custom to scroll by MouseWheel- Event.

如果您独立滚动并在这些处理程序中调用两个滚动函数,或者您是否在一个函数中同时滚动两个函数取决于您,如上所述.

If you scroll independently and call both scrolling functions at these handlers or if you scroll both in one function is up to you, as mentioned above.

由于需要为每个 tk.Text-Widget 调用滚动,我个人更喜欢在绑定到父窗口小部件的一个处理程序中调用两个滚动以及所有下面的处理程序(因此使用 bind_all),但我认为这是个人喜好问题.

As the scrolling needs to be called for each tk.Text-Widget I personally prefer calling both scrollings in one handler bound to the parent widget and all below (so using bind_all), but that is a matter of personal preference I think.

这篇关于Python tkinter,使两个文本小部件的滚动同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆