使用Tkinter文本编辑器突出显示错误

时间:2015-08-13 04:18:17

标签: python html user-interface tkinter

所以我用Tkinter编写了一个文本编辑器。我有一个txt文件,用于存储所有HTML标记。不幸的是,当我尝试通过逐行读取文件来为所有标记实现syntax highlighting时,标记之外的所有其他内容都会突出显示。这很奇怪,因为当我单独突出显示每个标记时,不会出现此问题。

import tkinter as tk


class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)


    def highlight_pattern(self, pattern, tag, start="1.0", end="end",
                          regexp=False):
        '''Apply the given tag to all text that matches the given pattern

        If 'regexp' is set to True, pattern will be treated as a regular
        expression.
        '''

        start = self.index(start)
        end = self.index(end)
        self.mark_set("matchStart", start)
        self.mark_set("matchEnd", start)
        self.mark_set("searchLimit", end)

        count = tk.IntVar()
        while True:
            index = self.search(pattern, "matchEnd","searchLimit",
                                count=count, regexp=regexp)
            if index == "": break
            self.mark_set("matchStart", index)
            self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.tag_add(tag, "matchStart", "matchEnd")

class Arshi(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.createtext()

    def highlight(self, argument):
        # Declaration (works)
        self.text.highlight_pattern("<!DOCTYPE HTML>", "htmlDeclaration")
        self.text.highlight_pattern("<!doctype html>", "htmlDeclaration")

        # tags (does not work)
        tags = []

        with open("html_tags.txt", "r") as taglist:
            for tag in taglist:
                tags.append(tag)

        for i in range(0, len(tags)):
            self.text.highlight_pattern(tags[i], "tags")

    def createtext(self):
        self.text = CustomText(self, bd=0, font=("Courier", 9))
        self.text.tag_configure("htmlDeclaration", foreground="#246BB2")
        self.text.tag_configure("tags", foreground="#006BB2")
        self.text.bind("<Key>", self.highlight)
        self.text.pack()

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Arshi")
    window = Arshi(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

下面是文本文件(名为html_tags.txt):

<a>
<abbr>
<acronym>
<address>
<applet>
<area>
<article>
<aside>
<audio>
<b>
<base>
<basefont>
<bdi>
<bdo>
<big>
<blockquote>
<body>
<br>
<button>
<canvas>
<caption>
<center>
<cite>
<code>
<col>
<colgroup>
<datalist>
<dd>
<del>
<details>
<dfn>
<dialog>
<dir>
<div>
<dl>
<dt>
<em>
<embed>
<fieldset>
<figcaption>
<figure>
<font>
<footer>
<form>
<frame>
<frameset>
<head>
<header>
<hr>
<html>
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<iframe>
<img>
<input>
<ins>
<kbd>
<keygen>
<label>
<legend>
<li>
<link>
<main>
<map>
<mark>
<menu>
<menuitem>
<meta>
<meter>
<nav>
<noframes>
<noscript>
<object>
<ol>
<optgroup>
<option>
<output>
<p>
<param>
<pre>
<progress>
<q>
<rp>
<rt>
<ruby>
<s>
<samp>
<script>
<section>
<select>
<small>
<source>
<span>
<strike>
<strong>
<style>
<sub>
<summary>
<sup>
<table>
<tbody>
<td>
<textarea>
<tfoot>
<th>
<thead>
<time>
<title>
<tr>
<track>
<tt>
<u>
<ul>
<var>
<video>
<wbr>

1 个答案:

答案 0 :(得分:2)

这是因为每个tag最后都有\n,这就是导致所有内容突出显示的原因。

您可以通过在tags添加一个简单的标记(不是按文件阅读),最后添加\n来重现类似的问题,例如 - tags = ['<html>\n']

然后<html>之后的任何一行都会突出显示。

在将每个标记添加到tags列表之前,您应该删除它们。

示例 -

import tkinter as tk


class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)


    def highlight_pattern(self, pattern, tag, start="1.0", end="end",
                          regexp=False):
        '''Apply the given tag to all text that matches the given 

pattern

        If 'regexp' is set to True, pattern will be treated as a 

regular
        expression.
        '''

        start = self.index(start)
        end = self.index(end)
        self.mark_set("matchStart", start)
        self.mark_set("matchEnd", start)
        self.mark_set("searchLimit", end)

        count = tk.IntVar()
        while True:
            index = self.search(pattern, "matchEnd","searchLimit",
                                count=count, regexp=regexp)
            if index == "": break
            self.mark_set("matchStart", index)
            self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.tag_add(tag, "matchStart", "matchEnd")

class Arshi(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.createtext()

    def highlight(self, argument):
        # Declaration (works)
        self.text.highlight_pattern("<!DOCTYPE HTML>", 

"htmlDeclaration")
        self.text.highlight_pattern("<!doctype html>", 

"htmlDeclaration")

        # tags (does not work)
        tags = []

        with open("html_tags.txt", "r") as taglist:
            for tag in taglist:
                tags.append(tag.strip())

        for i in range(0, len(tags)):
            self.text.highlight_pattern(tags[i], "tags")

    def createtext(self):
        self.text = CustomText(self, bd=0, font=("Courier", 9))
        self.text.tag_configure("htmlDeclaration", 

foreground="#246BB2")
        self.text.tag_configure("tags", foreground="#006BB2")
        self.text.bind("<Key>", self.highlight)
        self.highlight(None)
        self.text.pack()

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Arshi")
    window = Arshi(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

另外,一个建议 -

  1. 您可能希望将标签列表保留在列表中,而不是每次按键都从文件中读取标签。您可以将标记列表存储在self中作为实例变量。
  2. 此外,如果您在问题中发布的文件已完成,则不会突出显示结束标记(或内联关闭标记)。您可能需要单独将它们添加到文件中。