即使文本框较大

时间:2017-05-05 08:51:20

标签: python python-2.7 python-3.x tkinter

我正在尝试在滚动文本框的底部添加超链接样式覆盖,以便在用户将鼠标移到超链接上时显示状态栏类型标签(如webbrowser在左下角显示链接地址)。我开始使用effbot中的超链接管理器代码并对其进行修改以添加回调以设置文本的位:

try:
    from tkinter import scrolledtext
except ImportError:
    import ScrolledText as scrolledtext

class HyperlinkManager(object):
    """A class to easily add clickable hyperlinks to Text areas.
    Usage:
      callback = lambda : webbrowser.open("http://www.google.com/")
      text = tk.Text(...)
      hyperman = tkHyperlinkManager.HyperlinkManager(text)
      text.insert(tk.INSERT, "click me", hyperman.add(callback))
    From http://effbot.org/zone/tkinter-text-hyperlink.htm
    """
    def __init__(self, text, statusfunc=None):
        self.text = text
        self.statusfunc = statusfunc
        self.text.tag_config("hyper", foreground="blue", underline=1)
        self.text.tag_bind("hyper", "<Enter>", self._enter)
        self.text.tag_bind("hyper", "<Leave>", self._leave)
        self.text.tag_bind("hyper", "<Button-1>", self._click)
        self.reset()

    def reset(self):
        self.links = {}

    def add(self, action, tooltip=None):
        """Adds an action to the manager.
        :param action: A func to call.
        :return: A clickable tag to use in the text widget.
        """
        tag = "hyper-%d" % len(self.links)
        self.links[tag] = [action, tooltip]
        return ("hyper", tag)

    def _enter(self, event):
        self.text.config(cursor="hand2")
        for tag in self.text.tag_names(tk.CURRENT):
            if (tag[:6] == "hyper-"):
                tooltip = self.links[tag][1]
                if self.statusfunc:
                    self.statusfunc(tooltip) # don't care if no tooltip as function clears if it doesn't
                return

    def _leave(self, event):
        self.text.config(cursor="")
        if self.statusfunc:
            self.statusfunc()

    def _click(self, event):
        for tag in self.text.tag_names(tk.CURRENT):
            if (tag[:6] == "hyper-"):
                func = self.links[tag][0]
                if func:
                    func()
                return

class LinkScrolledText(scrolledtext.ScrolledText):
    def __init__(self, master=None, *args, **kwargs):
        scrolledtext.ScrolledText.__init__(self, master, *args, **kwargs)
        self.status = tk.Label(self)
        self._hyper = HyperlinkManager(self, self.showstatus)
        self.reset_links()

    def showstatus(self, status=None):
        print("showstatus: %s" % status)
        if status:
            self.status.configure(text=status)
            self.status.pack(side="bottom", anchor="w", fill=None)
        else:
            self.status.pack_forget()

    def reset_links(self):
        self._hyper.reset()

    def insert_hyperlink(self, position, text, action, tag=None, tooltip=None):
        tags = self._hyper.add(action, tooltip)
        if type(tag) == list:
            tags = tags + tag
        elif tag != None:
            tags.append(tag)
        self.insert(position, text, tags)

if __name__ == "__main__":
    try:
        import tkinter as tk
    except ImportError:
        import Tkinter as tk
    root = tk.Tk()
    tb = LinkScrolledText(root)
    tb.pack(fill="both", expand=True)
    tb.insert_hyperlink("end", "Test", action=None, tooltip="This is a test")
    root.mainloop()

但是,如果我在手动调整窗口大小之前将鼠标移到链接上,则在打开标签时窗口会缩小,一旦鼠标离开链接,窗口将重新显示其先前的大小。无需手动设置大小或关闭pack_propagate如何防止此行为?

注释:
    windows xp(但希望它能在所有平台上运行)     在python 2.7和3.4中进行了测试

1 个答案:

答案 0 :(得分:5)

为了不更改文本小部件的几何形状,您可以将状态标签放在内部而不是使用pack:

def showstatus(self, status=None):
    print("showstatus: %s" % status)
    if status:
        self.status.configure(text=status)
        self.status.place(relx=0, rely=1, anchor='sw')
    else:
        self.status.place_forget()