I am trying to write a small text editor using the StyledTextControl in wxPython. Most of the styling is working, but spaces remain unstyled and are shown as white areas, the picture shows the effect.
Sample Styled Text Control showing unstyled spaces
I have tried these functions, but with no effect.
self.SetWhitespaceForeground(0, wx.Colour(255, 255, 0))
self.SetWhitespaceBackground(0, wx.Colour(0, 0, 32))
The example is also setting the default foreground and background styles:
self.StyleSetBackground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(0,0,32))
self.StyleSetForeground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(255,255,0))
I cannot find any documentation that might suggest what I have done wrong, can anyone assist please.
I have written the following sample test script to recreate the issue:
import wx
import wx.stc as stc
MSSQL_KEYWORDS = "select insert update delete from exec create table not null"
MSSQL_DATATYPES = "int float money varchar datetime smalldatetime"
MSSQL_SYSTABLES = "sysdatabases sys"
MSSQL_GLOBAL_VARIABLES = "@@spid"
MSSQL_FUNCTIONS = "getdate()"
MSSQL_STORED_PROCEDURES = "sp_who"
class QueryEditor(stc.StyledTextCtrl):
def __init__(self, parent, font):
super().__init__(parent)
face_name = font.GetFaceName()
style_spec = f"face:{face_name},size:{font.PointSize}"
# Lexer
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, style_spec)
self.StyleClearAll()
self.SetLexer(stc.STC_LEX_MSSQL)
self.SetKeyWords(0, MSSQL_KEYWORDS)
self.SetKeyWords(1, MSSQL_DATATYPES)
self.SetKeyWords(2, MSSQL_SYSTABLES)
self.SetKeyWords(3, MSSQL_GLOBAL_VARIABLES)
self.SetKeyWords(4, MSSQL_FUNCTIONS)
self.SetKeyWords(5, MSSQL_STORED_PROCEDURES)
# Styles
self.StyleSetSpec(wx.stc.STC_MSSQL_COMMENT,'fore:#808080,italic,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_LINE_COMMENT,'fore:#808080,italic,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_NUMBER, 'fore:#008080,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_OPERATOR, 'fore:magenta,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_IDENTIFIER, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_VARIABLE, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_COLUMN_NAME, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_STATEMENT, 'fore:cyan,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_DATATYPE, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_SYSTABLE, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_GLOBAL_VARIABLE, 'fore:white,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_FUNCTION, 'fore:red,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_DATATYPE, 'fore:magenta,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_STORED_PROCEDURE, 'fore:yellow,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_DEFAULT_PREF_DATATYPE, 'fore:green,back:#000020')
self.StyleSetSpec(wx.stc.STC_MSSQL_COLUMN_NAME_2, 'fore:green,back:#000020')
self.SetWhitespaceForeground(True, wx.Colour(255,255,0))
self.SetWhitespaceBackground(True, wx.Colour(0,0,32))
self.StyleSetBackground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(0,0,32))
self.StyleSetForeground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(255,255,0))
# Margins & Caret
self.SetMargins(0, wx.stc.STC_MARGIN_NUMBER | wx.stc.STC_MARGIN_COLOUR)
self.SetMarginWidth(0, 40)
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "face:Menlo,size:10,fore:#000000,back:#C0C0C0")
self.SetCaretForeground(wx.Colour(255, 255, 0))
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="STC Sample", size=wx.Size(700,500))
font = wx.Font(wx.FontInfo(12).FaceName('Menlo'))
ed = QueryEditor(self, font)
ed.SetValue('''
SELECT @@SPID -- Global variable
SELECT getdate() -- function
exec sp_who -- Stored procedure
select * from sys.sysdatabases -- System table
-- A comment line
/*
** A comment block
*/
create table foo (
key_col int not null,
value_col varchar(25) null)
''')
self.Show()
if __name__ == "__main__":
app = wx.App(False)
MainFrame()
app.MainLoop()
2 Answers 2
You need to move the lines
self.StyleSetBackground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(0,0,32))
self.StyleSetForeground(wx.stc.STC_STYLE_DEFAULT, wx.Colour(255,255,0))
to before self.StyleClearAll(). The name StyleClearAll might be a little misleading. It pushes any style definitions set to wx.stc.STC_STYLE_DEFAULT to all of the other styles. Consequently any style definitions set for STC_STYLE_DEFAULT after that call won't have any effect.
The lines:
self.SetWhitespaceForeground(True, wx.Colour(255,255,0))
self.SetWhitespaceBackground(True, wx.Colour(0,0,32))
really only change the way whitespace is shown when you specifically ask for whitespace to be visible. This is usually done by showing a dot for each space and an arrow for each tab. To enable this, you must also call SetViewWhiteSpace(wx.stc.WS_VISIBLEALWAYS), but I don't think that's what you want here.
Comments
Add the default setting instead of "non-style" SetWhitespaceForeground and SetWhitespaceBackground:
self.StyleSetSpec(wx.stc.STC_MSSQL_DEFAULT, 'fore:#FFFF00,back:#000020')