StyledTextCtrl

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Huskyforce
User
Beiträge: 5
Registriert: Sonntag 6. April 2014, 11:54

Hallo,

ich hab die letzten Jahre mit C# und .NET verbracht seit kurzer Zeit habe ich dann Python und wx für mich endeckt.
Ich hatte früher mit Scintilla.NET einen Code Editor geschrieben und möchte ihn nun in Python mit wx umsetzen.
Nun ist mein Problem das ich den folgenden code in einem anderen Pythonscript haben möchte und ihn aber dann in meiner Editor.py ausführen möchte. Wie mach ich das?

Code: Alles auswählen

#default python styles
        self.StyleSetSpec(stc.STC_P_DEFAULT,
                          "fore:#000000,face:%(comic)s,size:%(sizeCode)d" % faces)

        # comments
        self.StyleSetSpec(stc.STC_P_COMMENTLINE,
                          "fore:#007F00,face:%(comic)s,size:%(sizeCode)d" % faces)
        # number
        self.StyleSetSpec(stc.STC_P_NUMBER,
                          "fore:#007F7F,size:%(sizeCode)d" % faces)
        # string
        self.StyleSetSpec(stc.STC_P_STRING,
                          "fore:#7F007F,face:%(comic)s,size:%(sizeCode)d" % faces)
        # single quoted string
        self.StyleSetSpec(stc.STC_P_CHARACTER,
                          "fore:#7F007F,face:%(comic)s,size:%(sizeCode)d" % faces)
         # comment blocks
        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
                          "fore:#7F7F7F,size:%(sizeCode)d" % faces)
        # keyword
        self.StyleSetSpec(stc.STC_P_WORD,
                          "fore:#00007F,bold,size:%(sizeCode)d" % faces)
        # triple quotes
        self.StyleSetSpec(stc.STC_P_TRIPLE,
                          "fore:#7F0000,size:%(sizeCode)d" % faces)
        # end of line were no string was closed
        self.StyleSetSpec(stc.STC_P_STRINGEOL,
                          "fore:#000000,face:%(comic)s,back:#E0C0E0,eol,size:%(sizeCode)d" % faces)
        # triple double quotes
        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
                          "fore:#7F0000,size:%(sizeCode)d" % faces)
        # class name definition
        self.StyleSetSpec(stc.STC_P_CLASSNAME,
                          "fore:#0000FF,bold,underline,size:%(sizeCode)d" % faces)
        # function or method name definition
        self.StyleSetSpec(stc.STC_P_DEFNAME,
                          "fore:#007F7F,bold,size:%(sizeCode)d" % faces)
        # operators
        self.StyleSetSpec(stc.STC_P_OPERATOR,
                          "bold,size:%(sizeCode)d" % faces)
        # identifiers
        self.StyleSetSpec(stc.STC_P_IDENTIFIER,
                          "fore:#000000,face:%(comic)s,size:%(sizeCode)d" % faces)
BlackJack

@Huskyforce: Also mir ist die Fragestellung nicht klar. Das da ist kein lauffähiger Quelltext. Der ist einfach so eingerückt und `self`, `stc`, und `faces` sind nicht definiert.
Huskyforce
User
Beiträge: 5
Registriert: Sonntag 6. April 2014, 11:54

Hier ist der gesammte Code.
Also ich möchte self.StyleSetSpec in einer anderen Klasse definieren damit ich in der Editor.py einfach nur sagen brauch zB Syntaxhighlighter.python()

Code: Alles auswählen

import wx
import wx.stc as stc
import keyword



if wx.Platform == '__WXMSW__':
    # for windows
    faces = \
        {
        'comic': 'Times New Roman',
        'sizeCode': 10,
        'sizeLn': 10,
        }
else:
    faces = \
        {
        'mono': 'Courier',
        'sizeCode': 10,
        'sizeLn': 10,
        }


class Editor(stc.StyledTextCtrl):

    def __init__(self, parent):
        stc.StyledTextCtrl.__init__(self, parent, wx.ID_ANY)

        # use code highlighting
        self.SetLexer(stc.STC_LEX_PYTHON)
        self.SetKeyWords(0, " ".join(keyword.kwlist))

        # set other options ...
        self.SetProperty("fold", "1")
        self.SetCaretForeground("red")

        # show line numbers
        self.SetMarginType(2, stc.STC_MARGIN_NUMBER)
        self.SetMarginSensitive(2, True)
        self.SetMarginWidth(2, 10)

        # square headers
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
                          stc.STC_MARK_BOXMINUS,          "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDER,
                          stc.STC_MARK_BOXPLUS,           "white",  "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,
                          stc.STC_MARK_VLINE,             "white",  "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
                          stc.STC_MARK_LCORNER,           "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
                          stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,
                          stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
                          stc.STC_MARK_TCORNER,           "white", "#808080")

        # global styles
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
                          "face:%(comic)s,size:%(sizeCode)d" % faces)
        # set  background color
        aliceBlue = '#F0F8FF'
        self.StyleSetBackground(style=stc.STC_STYLE_DEFAULT,
                                back=aliceBlue)
        # clear Style
        self.StyleClearAll()

        # more styles
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
                          "back:#C0C0C0,face:%(comic)s,size:%(sizeLn)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
                          "face:%(comic)s" % faces)
        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
                          "fore:#FFFFFF,back:#0000FF,bold")
        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
                          "fore:#000000,back:#FF0000,bold")

        #default python styles
        self.StyleSetSpec(stc.STC_P_DEFAULT,
                          "fore:#000000,face:%(comic)s,size:%(sizeCode)d" % faces)

        # comments
        self.StyleSetSpec(stc.STC_P_COMMENTLINE,
                          "fore:#007F00,face:%(comic)s,size:%(sizeCode)d" % faces)
        # number
        self.StyleSetSpec(stc.STC_P_NUMBER,
                          "fore:#007F7F,size:%(sizeCode)d" % faces)
        # string
        self.StyleSetSpec(stc.STC_P_STRING,
                          "fore:#7F007F,face:%(comic)s,size:%(sizeCode)d" % faces)
        # single quoted string
        self.StyleSetSpec(stc.STC_P_CHARACTER,
                          "fore:#7F007F,face:%(comic)s,size:%(sizeCode)d" % faces)
         # comment blocks
        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
                          "fore:#7F7F7F,size:%(sizeCode)d" % faces)
        # keyword
        self.StyleSetSpec(stc.STC_P_WORD,
                          "fore:#00007F,bold,size:%(sizeCode)d" % faces)
        # triple quotes
        self.StyleSetSpec(stc.STC_P_TRIPLE,
                          "fore:#7F0000,size:%(sizeCode)d" % faces)
        # end of line were no string was closed
        self.StyleSetSpec(stc.STC_P_STRINGEOL,
                          "fore:#000000,face:%(comic)s,back:#E0C0E0,eol,size:%(sizeCode)d" % faces)
        # triple double quotes
        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
                          "fore:#7F0000,size:%(sizeCode)d" % faces)
        # class name definition
        self.StyleSetSpec(stc.STC_P_CLASSNAME,
                          "fore:#0000FF,bold,underline,size:%(sizeCode)d" % faces)
        # function or method name definition
        self.StyleSetSpec(stc.STC_P_DEFNAME,
                          "fore:#007F7F,bold,size:%(sizeCode)d" % faces)
        # operators
        self.StyleSetSpec(stc.STC_P_OPERATOR,
                          "bold,size:%(sizeCode)d" % faces)
        # identifiers
        self.StyleSetSpec(stc.STC_P_IDENTIFIER,
                          "fore:#000000,face:%(comic)s,size:%(sizeCode)d" % faces)
BlackJack

@Huskyforce: Das geht natürlich so nicht, denn wie schon gesagt kann die Funktion ja nicht wissen was `self` und `faces` sind. Das müsste man da schon als Argument übergeben.

Allerdings finde ich die Richtung des Aufrufs und die Funktion für das Syntaxhighlighting für eine Programmiersprache auch ein wenig ungünstig. Das ist doch eigentlich keine Funktion sondern das sind Daten. Ich würde eher dem `Editor` eine Methode verpassen wo man das was in diesen immer gleichen Methodenaufrufen als Daten übergeben kann und dort dann in einer Schleife über die Konstanten/Wert-Paare gehen und die mit `StyledTextCtrl.StyleSetSpec()` setzen. Die Konstanten könnte man als Zeichenketten ohne den gemeinsamen Präfix angeben und den Wert mit `getattr()` vom `wx.stc`-Modul abfragen. Dann kann man die Einstellungen zum Beispiel aus einer JSON-Datei laden, die vom Benutzer des Editors verändert werden kann.

Der Schlüssel 'comic' um `faces`-Wörterbuch macht keinen Sinn. Comic ist ein Schriftartname, das ist also etwas was als Wert auftauchen würde, zum Beispiel für einen Schlüssel 'font'. Bei dem Schlüssel macht es dann auch Sinn den Wert 'Times' zuzuordnen. Und in `faces` sollten immer die gleichen Schlüssel gesetzt werden und nicht für jede Plattform unterschiedliche. Unter Nicht-Windows-Plattformen funktioniert das doch so wie es dort steht nicht, weil der Code einen Schlüssel mit dem Wert 'comic' bei den Zeichenkettenformatierungen erwartet, der aber nur unter Windows überhaupt in das Wörterbuch gesteckt wird.

Edit: Ich würde auch `format()` dem ``%`` vorziehen, weil man die Platzhalter Benutzern IMHO besser vermitteln kann.
Huskyforce
User
Beiträge: 5
Registriert: Sonntag 6. April 2014, 11:54

hm okay ich schau mal danke
Huskyforce
User
Beiträge: 5
Registriert: Sonntag 6. April 2014, 11:54

ich habs jetzt mal ganz anders versucht aber jededoch bekomm ich den fehler: TypeError: unbound method StyleSetSpec() must be called with Editor instance as first argument (got int instance instead)

python.py:

Code: Alles auswählen

import wx.stc as stc
import Editor as Editor
import __main__ as main


def load():

            #default python styles
        main.Editor.StyleSetSpec(stc.STC_P_DEFAULT,
                          "fore:#000000,face:%(font)s,size:%(sizeCode)d" % Editor.faces)

        # comments
        main.Editor.StyleSetSpec(stc.STC_P_COMMENTLINE,
                          "fore:#007F00,face:%(font)s,size:%(sizeCode)d" % Editor.faces)
        # number
        main.Editor.StyleSetSpec(stc.STC_P_NUMBER,
                          "fore:#007F7F,size:%(sizeCode)d" % Editor.faces)
        # string
        main.Editor.StyleSetSpec(stc.STC_P_STRING,
                          "fore:#7F007F,face:%(font)s,size:%(sizeCode)d" % Editor.faces)
        # single quoted string
        main.Editor.StyleSetSpec(stc.STC_P_CHARACTER,
                          "fore:#7F007F,face:%(font)s,size:%(sizeCode)d" % Editor.faces)
         # comment blocks
        main.Editor.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
                          "fore:#7F7F7F,size:%(sizeCode)d" % Editor.faces)
        # keyword
        main.Editor.StyleSetSpec(stc.STC_P_WORD,
                          "fore:#00007F,bold,size:%(sizeCode)d" % Editor.faces)
        # triple quotes
        main.Editor.StyleSetSpec(stc.STC_P_TRIPLE,
                          "fore:#7F0000,size:%(sizeCode)d" % Editor.faces)
        # end of line were no string was closed
        main.Editor.StyleSetSpec(stc.STC_P_STRINGEOL,
                          "fore:#000000,face:%(font)s,back:#E0C0E0,eol,size:%(sizeCode)d" % Editor.faces)
        # triple double quotes
        main.Editor.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
                          "fore:#7F0000,size:%(sizeCode)d" % Editor.faces)
        # class name definition
        main.Editor.StyleSetSpec(stc.STC_P_CLASSNAME,
                          "fore:#0000FF,bold,underline,size:%(sizeCode)d" % Editor.faces)
        # function or method name definition
        main.Editor.StyleSetSpec(stc.STC_P_DEFNAME,
                          "fore:#007F7F,bold,size:%(sizeCode)d" % Editor.faces)
        # operators
        main.Editor.StyleSetSpec(stc.STC_P_OPERATOR,
                          "bold,size:%(sizeCode)d" % Editor.faces)
        # identifiers
        main.Editor.StyleSetSpec(stc.STC_P_IDENTIFIER,
                          "fore:#000000,face:%(font)s,size:%(sizeCode)d" % Editor.faces)
Editor.py

Code: Alles auswählen

import wx
import wx.stc as stc
import keyword
import python


faces = \
    {
    'font': 'Times New Roman',
    'sizeCode': 10,
    'sizeLn': 10,
    }


class Editor(stc.StyledTextCtrl):

    def __init__(self, parent):
        stc.StyledTextCtrl.__init__(self, parent, wx.ID_ANY)

        # use code highlighting
        self.SetLexer(stc.STC_LEX_PYTHON)
        self.SetKeyWords(0, " ".join(keyword.kwlist))

        # set other options ...
        self.SetProperty("fold", "1")
        self.SetCaretForeground("red")

                # show line numbers
        self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
        self.SetMarginSensitive(1, True)
        self.SetMarginWidth(1, 70)

        # square headers
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
                          stc.STC_MARK_BOXMINUS,          "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDER,
                          stc.STC_MARK_BOXPLUS,           "white",  "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,
                          stc.STC_MARK_VLINE,             "white",  "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
                          stc.STC_MARK_LCORNER,           "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
                          stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,
                          stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
        self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
                          stc.STC_MARK_TCORNER,           "white", "#808080")

        # global styles
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
                          "face:%(font)s,size:%(sizeCode)d" % faces)
        # set  background color
        aliceBlue = '#F0F8FF'
        self.StyleSetBackground(style=stc.STC_STYLE_DEFAULT,
                                back=aliceBlue)
        # clear Style
        self.StyleClearAll()

        # more styles
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
                          "back:#C0C0C0,face:%(font)s,size:%(sizeLn)d" % faces)
        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
                          "face:%(font)s" % faces)
        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
                          "fore:#FFFFFF,back:#0000FF,bold")
        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
                          "fore:#000000,back:#FF0000,bold")
        python.load()
__main__.py

Code: Alles auswählen

import buttonevents
from Editor import *


class Pyrura(wx.Frame):

    edit = Editor

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(800, 600))

        edit = Editor(self)

        self.CreateStatusBar()
        #Set up the menu
        filemenu = wx.Menu()

        menuAbout = filemenu.Append(wx.ID_ABOUT, "&About", "Information about the Application")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        filemenu.AppendSeparator()

        #Creates exit button
        menuExit = filemenu.Append(wx.ID_EXIT, "&Exit", "Terminates the Application")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        #Create the menubar
        menubar = wx.MenuBar()
        menubar.Append(filemenu, "&File")
        self.SetMenuBar(menubar)

        #Centre the window on startup
        self.Centre()
        self.Show(True)

    # If about were clicked show up a info dialog
    def OnAbout(self, e):
        buttonevents.createInfoDlg(self)

    # If exit were clicked terminate the application
    def OnExit(self, e):
        buttonevents.ExitApp(self)


app = wx.App(0)
frame = Pyrura(None, "Pyrura")
app.MainLoop()
BlackJack

@Huskyforce: Du versuchst da ja auch die Methode auf der Klasse aufzurufen statt auf einem `Editor`-Exemplar. Und so ein Exemplar gibt es zu dem Zeitpunkt auch noch gar nicht.

Als erstes solltest Du keine zirkulären Importe versuchen. `__main__` importiert `Editor`, und `Editor` importiert `python`, und das importiert dann wieder `__main__`. Und zwischen `Editor` und `python` das gleiche — die importieren sich gegenseitig. Das funktioniert nicht so wie Du das vielleicht denkst. Selbst wenn man verstanden hat, wann da welcher Code in welchem Modul tatsächlich ausgeführt wird, sollte man solche Hacks besser sein lassen. Wenn sich Module gegenseitig benötigen, dann stellt sich nämlich die Frage warum der Code darin überhaupt in verschiedenen Modulen steckt, wenn man ihn gar nicht vernünftig trennen kann. Wenn man die Importbeziehungen von Modulen grafisch darstellt, dann sollte da eine Baumstruktur bei heraus kommen und kein Graph mit Kreisen.

Das `buttonevents`-Modul schaut auch eigenartig aus. Man sollte in Modulen Funktionen und Klassen zusammenfassen die *thematisch* zusammengehören, und nicht weil sie den gleichen Typ haben. Das ist ein bisschen als wenn man Bücher nach Farbe und Grösse sortiert, und nicht nach Fachgebiet/Inhalt. Ersteres sieht zwar schön aufgeräumt aus, hilft aber überhaupt nicht sich darin zurecht zu finden. Im Gegenteil.
Huskyforce
User
Beiträge: 5
Registriert: Sonntag 6. April 2014, 11:54

hm naja sind vllt c# angewohnheiten

da war es mit scintilla.net ganz einfach sowas wie ich versucht hab zu bauen ich komm einfach iwie grad nicht weiter
Antworten