I am trying to utilize pygment for some code highlighting in a wxPython RichTextCtrl.
I can't find much online (other than broken links) about achieving this.
Here is some sample code. I've tried a few different formatters and they all fail. I believe editra using pygment and wxpython, but the source is difficult to navigate.
import wx
import wx.richtext
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters.rtf import RtfFormatter
lexer = get_lexer_by_name("python", stripall=True)
formatter = RtfFormatter()
code = """ # Comment
a = 5
print(a)
print(b)
"""
formatted_code = highlight(code, lexer, formatter)
########################################################################
class MyFrame(wx.Frame):
# ----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, title='Richtext Test')
sizer = wx.BoxSizer(wx.VERTICAL)
self.rt = wx.richtext.RichTextCtrl(self)
self.rt.SetMinSize((300, 200))
self.rt.ChangeValue(formatted_code)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.rt, 1, wx.EXPAND | wx.ALL, 6)
self.SetSizer(sizer)
self.Show()
# ----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Thanks for any help
I ended up using StyledTextCtrl as suggested in the comments. It turns out there are 2 demos included with the wxPython source, the 2nd of which does exactly what I was trying. I would post the code but it is ~400 lines.
Related
I am a newbie in wx.python and python and wanted to use the MultiSplitterWindow.py demo code in my own application.
I have read other stackoverflow entries regarding this subject but the answers given there don't seem to work for me.
I would really appreciate if anybody could help me to solve this issue.
As the demos use the demo framework:
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
It does not work in my app, I have tried replacing the above using the example given in:
[] http://wiki.wxpython.org/Using%20wxPython%20Demo%20Code
But I might be doing something wrong because I does not work.
Any help is much appreciated.
I wrote about this on the wxPython wiki:
http://wiki.wxpython.org/Using%20wxPython%20Demo%20Code
Most of the time, you can copy the relevant portions of the widget code in question and paste it in your own code. The part you don't want is the references to self.log. That just allows the demo to log the messages and is demo specific code. I would actually rewrite my initial example to look like the following though:
import wx
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
########################################################################
class MyFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, title="Demo Test")
panel = MyPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Now if you want to copy the code in from the demo, you won't have to change all the self instances to `self.panel':
import wx
from wx.lib.wordwrap import wordwrap
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
b = wx.Button(self, -1, "Show a wx.AboutBox", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
# First we create and fill the info object
info = wx.AboutDialogInfo()
info.Name = "Hello World"
info.Version = "1.2.3"
info.Copyright = "(C) 2006 Programmers and Coders Everywhere"
info.Description = wordwrap(
"A \"hello world\" program is a software program that prints out "
"\"Hello world!\" on a display device. It is used in many introductory "
"tutorials for teaching a programming language."
"\n\nSuch a program is typically one of the simplest programs possible "
"in a computer language. A \"hello world\" program can be a useful "
"sanity test to make sure that a language's compiler, development "
"environment, and run-time environment are correctly installed.",
350, wx.ClientDC(self))
info.WebSite = ("http://en.wikipedia.org/wiki/Hello_world", "Hello World home page")
info.Developers = [ "Joe Programmer",
"Jane Coder",
"Vippy the Mascot" ]
info.License = wordwrap(licenseText, 500, wx.ClientDC(self))
# Then we call wx.AboutBox giving it that info object
wx.AboutBox(info)
########################################################################
class MyFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, title="Demo Test")
panel = MyPanel(self)
self.Show()
licenseText = "blah " * 250 + "\n\n" +"yadda " * 100
#----------------------------------------------------------------------
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Download demos from here http://wxpython.org/download.php install and go C:\Program Files\wxPython3.0-Docs-and-Demos\demo and run.
I was working through the third video in this tutorial series in my effort to learn WxPython. I typed the code as in the video but an error is still returned. I am guessing this has something to do with the WxPython or Python version used. He is using Python 2.4, I am using 2.7.5 and I don't know what WxPython version he is using but I am using 3.0.0.
This is the code:
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (400,200), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
self.control = wx.TextCtrl(self,1,style = wx.TE_MULTILINE)
self.Show(True)
app = wx.PySimpleApp()
frame = MainWindow(None,-1,"Small Editor")
app.MainLoop()
Invalid syntax is returned for self.control but I don't know why.
Any help is appreciated,
Fluffy
It looks like you're missing the final enclosing parenthesis on the line directly above.
Generally speaking, syntax errors are typically due to misspellings, missing characters, or other such mistakes, and can either be found on the line indicated by the stacktrace or the line directly above.
Once the parenthesis is added, the below code runs for me:
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (400,200), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.control = wx.TextCtrl(self,1,style = wx.TE_MULTILINE)
self.Show(True)
app = wx.PySimpleApp()
frame = MainWindow(None,-1,"Small Editor")
app.MainLoop()
On Linux, how do you disable re-sizing, but at the same time maximize the interface to begin with?
I have tried the following but it is not maximized:
style = wx.DEFAULT_FRAME_STYLE & ~wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER)
style = wx.MAXIMIZE | wx.DEFAULT_FRAME_STYLE & ~wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER
EDIT:
Tried Maximize() with resize disabled, still nothing. My versions: Linux, Python 2.4, wxPython 2.8.12.1
(style = wx.MAXIMIZE works for Windows, but not for Linux)
You're pretty close. You just forgot to call Maximize(). See below:
import wx
########################################################################
class NoResizeFrame(wx.Frame):
"""
This frame cannot be resized. It can only be minimized, maximized
and closed
"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
wx.RESIZE_BOX |
wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, None, title="No Resize", style=no_resize)
panel = wx.Panel(self)
self.Show()
self.Maximize()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = NoResizeFrame()
app.MainLoop()
You might find this tutorial of mine useful for better understanding frame style flags:
http://www.blog.pythonlibrary.org/2013/11/06/wxpython-101-using-frame-styles/
Or this slightly older tutorial on maximizing:
http://www.blog.pythonlibrary.org/2013/07/12/wxpython-making-your-frame-maximize-or-full-screen/
I'm trying to update some static text using a timer and the output of a function.
The code is here: code.
I know very little about wxPython, it's one of the many things that I just don't get and this is maddening, if I print the output of apper to console it works perfectly, all I want to do is have what prints out to the console applied to the text.
What am I doing wrong?
Timers can be a pain to use, an easier way is to use the functions wx.CallAfter and/or wx.CallLater - also these functions are thread-safe and can be used to invoke functions on the GUI thread from other worker threads. Here is a sample...
import random
import wx
class Frame(wx.Frame):
def __init__(self):
super(Frame, self).__init__(None)
self.SetTitle('Title')
panel = wx.Panel(self)
style = wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE
self.text = wx.StaticText(panel, style=style)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.AddStretchSpacer(1)
sizer.Add(self.text, 0, wx.EXPAND)
sizer.AddStretchSpacer(1)
panel.SetSizer(sizer)
self.on_timer()
def on_timer(self):
self.text.SetLabel(str(random.randint(0, 100)))
wx.CallLater(1000, self.on_timer)
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()
i am trying to develop python GUI to access webpages. below example is working fine. but i need to pass user credentials(username/password) with in this code.
i dont want to click on that button. just i need to fill text boxes in login page
import wx
import wx.html2
class MyBrowser(wx.Dialog):
def __init__(self, *args, **kwds):
wx.Dialog.__init__(self, *args, **kwds)
sizer = wx.BoxSizer(wx.VERTICAL)
self.browser = wx.html2.WebView.New(self)
self.browser.LoadURL("http://wiki.python.org/moin/GuiProgramming?action=login")
sizer.Add(self.browser, 1, wx.EXPAND, 10)
self.SetSizer(sizer)
self.SetSize((700, 700))
if __name__ == '__main__':
app = wx.App()
dialog = MyBrowser(None, -1)
dialog.Show()
app.MainLoop()
The "Use javascript" answer is certainly helpful, but with recent versions of wxPython anyway, it won't run unless wx.html2.EVT_WEB_VIEW_LOADED is changed to wx.html2.EVT_WEBVIEW_LOADED ("WEB_VIEW changed to "WEBVIEW").
Use javascript. Simple sample code below.
import wx
import wx.html2
class MyBrowser(wx.Dialog):
def __init__(self, *args, **kwds):
wx.Dialog.__init__(self, *args, **kwds)
sizer = wx.BoxSizer(wx.VERTICAL)
self.browser = wx.html2.WebView.New(self)
self.browser.LoadURL("http://wiki.python.org/moin/GuiProgramming?action=login")
sizer.Add(self.browser, 1, wx.EXPAND, 10)
self.SetSizer(sizer)
self.SetSize((700, 700))
# We have to bind an event so the javascript is only run once the page
# is loaded.
self.Bind(wx.html2.EVT_WEB_VIEW_LOADED, self.OnPageLoaded,
self.browser)
def OnPageLoaded(self, evt):
self.browser.RunScript("""
// There are probably better ways to get the elements you
// want, but this works.
document.getElementsByName('name')[0].value="hist";
document.getElementsByName('password')[0].value="bar";
document.getElementById('openididentifier').value="ident";
// If you want to submit the form you can use something like
//document.getElementsByName('login')[1].click()
""")
# And you probably want to unbind the event here
self.Bind(wx.html2.EVT_WEB_VIEW_LOADED, None,
self.browser)
if __name__ == '__main__':
app = wx.App()
dialog = MyBrowser(None, -1)
dialog.Show()
app.MainLoop()
I would check out Selenium. It's an open source web navigating automation tool which has developed an awesome module for python. I've used it to automate logging into multiple different websites and you could easily slap a wx GUI on top of it.