0

I have created a gui that only displays a quote. How can I change the color of all of the word 'thou' in the quote below into blue?. I have tried SetForegroundColour but it changes the entire text into blue.

Here is the code:

import wx

string='''"Have more than thou showest,

Speak less than thou knowest,

Lend less than thou owest,

Ride more than thou goest,

Learn more than thou trowest,

Set less than thou throwest."

β€”The Fool in King Lear'''

class Quote(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.InitUI()

    def InitUI(self):
        panel=wx.Panel(self)

        self.text=wx.TextCtrl(panel, pos=(20,20), size=(250,220),
            style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.text.AppendText(string)
        self.text.SetForegroundColour("blue")

        self.SetSize(300,300)
        self.Centre()
        self.Show(True)

def main():
    app=wx.App()
    Quote(None)
    app.MainLoop()

if __name__ == '__main__':
    main()

Here's how it looks like

Nuh Yamin
  • 343
  • 3
  • 15

1 Answers1

1

You probably need to read up on RichTextCtrl https://wxpython.org/Phoenix/docs/html/richtextctrl_overview.html

Just using TextCtrl you can
1 set style attributes after the fact (Thanks Robin for your comment) or
2 apply style attributes to the text as you go.

Setting style attributes after the fact using re to find all occurrences of your word beforehand:

import wx
import re

string='''"Have more than thou showest,

Speak less than thou knowest,

Lend less than thou owest,

Ride more than thou goest,

Learn more than thou trowest,

Set less than thou throwest."

-The Fool in King Lear'''

class Quote(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, None, -1)
        self.InitUI()

    def InitUI(self):
        panel=wx.Panel(self)
        word = 'thou'
        word_colour = wx.TextAttr(wx.BLUE)
        word_occurs = self.find_str(word,string)
        self.text=wx.TextCtrl(panel, pos=(20,20), size=(250,220),
            style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.text.AppendText(string)
        for i in word_occurs:
            #SetStyle(start pos, end pos, style)
            self.text.SetStyle(i,i+len(word),word_colour)
        self.SetSize((300,300))
        self.Centre()
        self.Show(True)

    def find_str(self,sub,sent): #return positions of the word
        return [x.start() for x in re.finditer(sub,sent)]

def main():
    app=wx.App()
    Quote()
    app.MainLoop()

if __name__ == '__main__':
    main()

The long winded way of doing this, applying style attributes as you go:

import wx

string1='''"Have more than'''
string2='''showest,

Speak less than'''
string3='''knowest,

Lend less than'''
string4='''owest,

Ride more than'''
string5='''goest,

Learn more than'''
string6='''trowest,

Set less than'''
string7='''throwest."

-The Fool in King Lear'''

class Quote(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, None, -1)
        self.InitUI()

    def InitUI(self):
        panel=wx.Panel(self)

        self.text=wx.TextCtrl(panel, pos=(20,20), size=(250,220),
            style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.text.AppendText(string1)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string2)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string3)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string4)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string5)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string6)
        self.text.SetDefaultStyle(wx.TextAttr(wx.BLUE))
        self.text.AppendText(" thou ")
        self.text.SetDefaultStyle(wx.TextAttr(wx.NullColour))
        self.text.AppendText(string7)

        self.SetSize((300,300))
        self.Centre()
        self.Show(True)

def main():
    app=wx.App()
    Quote()
    app.MainLoop()

if __name__ == '__main__':
    main()

enter image description here

Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
  • You can also use `SetStyle` to change the style on an existing range of text. So you could put the whole string in the control in one step, and then set the styles at the appropriate start/end positions. – RobinDunn Sep 20 '17 at 17:06
  • @RobinDunn I learn more answering questions than I ever have by asking one! :) – Rolf of Saxony Sep 21 '17 at 08:09
  • Thanks, Rolf of Saxony. Your answer is very useful. – Nuh Yamin Sep 22 '17 at 03:37