2017-10-06 51 views
0

我想創建一個文本編輯器,它將操縱像對象一樣的字符串。理想情況下,我想繼承Tkinter的Text Widget或其他一些Gui模塊,以允許我替換此自定義對象而不是使用字符串。是否有可能在Tkinter Text Widget(python)中使用自定義對象而不是字符串?

我明白如何創建對象本身(本質上只是用元數據標記每個單詞),但不知道如何操作呈現的對象作爲文本,同時保留其他屬性。

例如,
文本編輯器導入包含「Hello World」的文件。在打開這個文本時,兩個單詞都被標記了相關的屬性。 (下面顯示的字典,但理想的對象Hello.strContent,Hello.index等)

Hello={strContent: "Hello", index: 0, speaker: "Joe", paragraph: 3} 
World={strContent: "World", index: 1, speaker: "Joe", paragraph: 3} 

現在我完全雖然我怎麼可能讓這些字符串如可操作對象難倒,並受到切割,複製,粘貼,刪除和重新排列,在文本gui中。我不需要程序允許我鍵入任何新詞或創建新對象,只需操作轉換打開的文件時已初始化的對象即可。

任何幫助或方向將不勝感激。謝謝。

+0

是不是有一個原因,你不能只是將'strContent'作爲字符串添加到文本中,或者甚至引用字典中的每個對象?如在中,每個單詞都是一個字典鍵,其中分配給該鍵的值是上面列出的字典? –

+0

我喜歡使用字典的想法,但源文本將包含相同單詞的重複。例如,一個醜陋的解決方案將使用索引附加到每個單詞的開頭。
00和01here 02is 03a 04sample 05text 06whis 07is 08simple。
現在,假設我在我們假設的Gui編輯器中編輯了這段文字:
Acronomic

+0

您可以創建一個列表嗎?將每個對象追加到列表中,然後遍歷列表並將每個'strContent'添加到'text'小部件中? –

回答

0

我認爲你可以做這樣的事情

class myobj: 
    def __init__(self, text): 
     self.strContent=text 
hello = [[myobj("Hello"), myObj("World")], [myobj("Paragraph"), myobj("2")]] 

那麼每當你需要顯示的文字,你會擁有它遍歷像這樣

printableStr = "" 
for paragraph in hello: 
    for word in paragraph: 
     printableStr += word.strContent + " " 
    printableStr += "\n" 

然後printableStr將是一個不錯的包含來自你好的所有信息的字符串

+0

這絕對適用於顯示文本,但我期望在文本顯示後對其進行操作,並讓每個單詞仍保留其元數據。理想情況下,它可以在像app這樣的文本編輯器中進行操作,但是操縱myObjs而不是字符串。 – Acronomic

1

注意:這試圖回答被問到的問題,但我懷疑這是一個xy problem。在回答結束時,我會提出一些其他建議。


文本小部件不能有一些複雜的對象作爲其基礎數據結構。它可以顯示文本,並且可以有與文本關聯的標籤。您也可以插入圖片和小工具,但我認爲這與您所問的無關。

在讀取數據時,可以爲每條元數據構造標籤,並將這些標籤與一定範圍的文本相關聯。例如,單詞「你好」可能有標籤「段落:3」,「揚聲器:喬」和「索引:0」。 「世界是相似的,除了它會標記‘指數:1’

這會很容易在最初顯示的數據做例如:。

data = [{"strContent": "Hello", "index": 0, "speaker": "Joe", "paragraph": 3}, 
     {"strContent": "World", "index": 1, "speaker": "Joe", "paragraph": 3} 
] 

for item in data: 
    tags = (
     "index:%d" % item['index'], 
     "speaker:%s" % item['speaker'], 
     "paragraph:%d" % item['paragraph'] 
    ) 
    self.text.insert("end", item['strContent'], tags) 

如果你再進去在「World」中插入「r」,它會繼承周圍文本的標籤

您可以使用返回數據流的dump方法從窗口小部件中獲取數據,例如, self.text.dump("1.0", "end-1c", tag=True, text=True, mark=False)產生以下信息:

[ 
('tagon', 'paragraph:3', '1.0'), 
('tagon', 'speaker:Joe', '1.0'), 
('tagon', 'index:0', '1.0'), 
('text', 'Hello', '1.0'), 
('tagoff', 'index:0', '1.5'), 
('tagon', 'index:1', '1.5'), 
('text', 'World', '1.5') 
] 

將數據重新組裝爲原始格式非常棘手。這是一個粗略的嘗試,儘管我不知道它會如何在現實世界中站起來。用戶可能會以完全混淆結構的方式編輯數據。

def get_data(self): 
    result = [] 
    meta = {} 
    for item in self.text.dump("1.0", "end-1c", tag=True, text=True, mark=False): 
     if item[0] == "tagon": 
      (name, value) = item[1].split(":") 
      meta[name] = value 

     if item[0] == "tagoff": 
      (name, value) = item[1].split(":") 
      del meta[name] 

     if item[0] == "text": 
      text = item[1] 
      # if this text has the same tags as the previous text, 
      # don't create a new item; instead, append the text to 
      # the previous item 
      if result and all(item in result[-1].items() for item in meta.items()): 
       result[-1]["strContent"] += text 
      else: 
       data = {"strContent": text} 
       data.update(meta) 
       result.append(data) 

    return result 

不知道你實際上試圖完成,文本構件可能不是最好的解決方案,因爲它爲用戶提供了一個有點過分自由改變文本。例如,如果他們將「Hello」更改爲「HelloWorld」,然後刪除原始的「World」,會發生什麼?他們最終會得到一個「HelloWorld」項目還是原來的兩個「Hello」和「World」項目?

您可能想要考慮使用一個畫布,其中每個文本項目都是不同的對象(也可以有標籤),或者您可能想要使用一系列的入口小部件,以便一次中的數據可以' t流血到另一個。

+0

謝謝布萊恩。理想情況下,每個單詞應該保持自己作爲一個獨特的對象,文本不應該是可變的。這個詞只應該受制於操作:插入(重新定位),刪除或複製(和插入)。畫布小部件似乎是一個很好的建議,但我擔心易於使用以執行上述操作。該用例涉及多頁腳本,我想編輯,每個單詞保持它的標籤。我會盡力實施你所提到的。謝謝你的幫助。 – Acronomic

相關問題