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

标签 python html user-interface tkinter

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

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>

最佳答案

因为每个 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中作为实例变量。

此外,如果您在问题中发布的文件是完整的,那么您就不会突出显示结束标记(或内联结束标记)。您可能需要将它们单独添加到文件中。

关于python - 使用 Tkinter 文本编辑器突出显示错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31979431/

相关文章:

html - 将一个 div 在另一个 div 内水平居中 - 不允许使用滚动条

android - 如何在 onitemclick 的 webview 中加载 HTML 文件

apache-flex - 弹性 : How to create an entirely new component?

c++ - 在Qt中创建一个依赖于父窗口但出现在父窗口之外的新窗口

python - 为什么十进制模给出错误的符号?

python - 即使整个管道都安装了,管道中的 Sklearn 组件也没有安装?

javascript - 安全的 .php 文件,通过 JavaScript 调用

python - 运行 django celery 时出现段错误

python - 理解Python中的递归和堆栈

java - 如何将模态对话附加到 JavaFX 中的主窗口?