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.
Related
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'm implementing the help menu of an App done in wxPython. By now, I'm using a txt file opened in a frame. I would like to have hyperlinks in the help text in order to open other txt files in the same frame. However, I don't know how to do this. I don't even know if this is the most elegant way to implement a help menu. Any suggestion will be very useful.
Below you can find part of the code I'm using (you will need a txt file called "Help_Main_App.txt"):
import wx
class Help_Frame(wx.Frame):
title = "Help, I need somebody, help..."
def __init__(self):
wx.Frame.__init__(self, wx.GetApp().TopWindow, title=self.title, size=(450,500))
self.CreateStatusBar()
panel = wx.Panel(self, wx.ID_ANY)
panel.SetBackgroundColour('#ededed')
self.Centre()
vBox = wx.BoxSizer(wx.VERTICAL)
hBox = wx.BoxSizer(wx.HORIZONTAL)
self.textbox = wx.TextCtrl(panel, style=wx.TE_MULTILINE, size=(-1, 295))
hBox.Add(self.textbox, 1, flag=wx.EXPAND)
vBox.Add(hBox, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)
panel.SetSizer(hBox)
defaultdir, filename = './', 'Help_Main_App.txt'
self.filePath = '/'.join((defaultdir, filename))
self.textbox.LoadFile(self.filePath)
self.textbox.Disable()
class Main_Window(wx.Frame):
def __init__(self, parent, title):
#wx.Frame.__init__(self, parent, title = title, pos = (0, 0), size = wx.DisplaySize())
wx.Frame.__init__(self, parent, title=title, size=(1000,780))
self.Center()
# Setting up the menu.
filemenu = wx.Menu()
helpmenu = wx.Menu()
menuExit = filemenu.Append(wx.ID_EXIT,"&Exit"," Close window and exit program")
menuHelp = helpmenu.Append(wx.ID_HELP, "&Help"," Help of this program")
# Creating the menubar.
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
menuBar.Append(helpmenu,"&Help") # Adding the "helpmenu" to the MenuBar
self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
# Set event handlers
self.Bind(wx.EVT_MENU, self.OnHelp, menuHelp)
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
def OnHelp(self,e):
Help_Frame().Show()
def OnExit(self,e):
self.Close(True) # Close the frame.
def main():
app = wx.App(False)
frame = Main_Window(None, "Main App")
frame.Show()
app.MainLoop()
if __name__ == "__main__" :
main()
I recommend using an HTMLWindow for something simple like that. It can handle only simple HTML, so don't try to make a website with it as HTMLWindow doesn't support CSS or javascript.
I wrote a simple About box using it. You can read about it here:
http://www.blog.pythonlibrary.org/2008/06/11/wxpython-creating-an-about-box/
The basic idea is to subclass HTMLWindow and override its OnLinkClicked method. Then you can use Python's webbrowser to open the user's default browser. Or you can try using subprocess, although that will be a lot less likely to work unless you always know what is installed on your target machines.
Further to Mikes answer if you are able to use wxPython 2.9.4 or above you can consider using the more advanced html2 webview which does support CSS and javascript. Using this you could make the help as a simple website that can be viewed in program.
http://wxpython.org/Phoenix/docs/html/html2.WebView.html
Its also worth mentioning that if (for some strange reason) you don't want to work with you could achieve a similar outcome with a StyledTxtCtrl.
Late to the party but just for the sake of completeness (seeing that the OP's code was using wx.TextCtrl to show the help text), here is an example on how to add and launch hyperlinks using wx.TextCtrl (I have attached any explanations on the code comments):
class HelpDialog(wx.Dialog):
"""Help Dialog."""
def __init__(self, parent, title, style):
"""Init."""
wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY,
title=title, pos=wx.DefaultPosition, size=wx.DefaultSize, style=style)
# We need the 'wx.TE_AUTO_URL' style set.
self.help = wx.TextCtrl(self, wx.ID_ANY, '', DPOS, DSIZE,
wx.TE_AUTO_URL|wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2|wx.TE_WORDWRAP)
# Events - this is the interesting part,
# we catch the mouse on hovering the hyperlink:
self.help.Bind(wx.EVT_TEXT_URL, self.openHlpUrl)
# Show dialog
self.ShowModal()
def openHlpUrl(self, event):
"""Open help URL."""
# We get the starting and ending points on
# the text stored in our ctrl from this event
# and we slice it:
url = self.help.GetValue()[event.GetURLStart():event.GetURLEnd()]
# We want to capture the left up mouse event
# when hovering on the hyperlink:
if event.MouseEvent.LeftDown():
# Let's be wxpythion native and launch the browser this way:
wx.LaunchDefaultBrowser(url)
I'm trying to get my empty frame so that when I click the X it just hides the window, and then if I hit the dock icon it'll reveal the window. It's turning out to be more of a challenge than I expected.. I used http://wiki.wxpython.org/Optimizing%20for%20Mac%20OS%20X/ but I can't make ends of it.
Here's my code:
import wx
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "title",style=wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CAPTION, size=(300,300))
panel = wx.Panel(self)
def MacReopenApp(self, event):
print "Attempting to reveal the window."
def MacHideApp(self, event):
print "Attempting to hide the window."
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()
The document you link to states that you need to add those event handlers on the App. You have currently defined them on a frame. So you need to extend wx.App and define those event handlers, and instantiate your own App instead of wx.App.
So (shortened example copied from your link):
class MyApp(wx.App):
def __init__(self, *args, **kwargs):
wx.App.__init__(self, *args, **kwargs)
# This catches events when the app is asked to activate by some other
# process
self.Bind(wx.EVT_ACTIVATE_APP, self.OnActivate)
#.....
def MacReopenApp(self):
"""Called when the doc icon is clicked, and ???"""
self.BringWindowToFront()
app = MyApp(False)
app.MainLoop()
I'm trying to create something like the categories panel in Wordpress, with wxPython.
What I'm trying to figure out, is how to add a widget when the user clicks a button (like "Add New Category")
Here is my code:
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(300,200))
self.panel = wx.Panel(self, -1)
button = wx.Button(self.panel,-1,"Button")
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(button)
add_btn = wx.Button(self.panel,-1,"Add")
add_btn.Bind(wx.EVT_BUTTON, self.add)
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(add_btn)
main_vbox = wx.BoxSizer(wx.VERTICAL)
main_vbox.Add(self.vbox)
main_vbox.Add(hbox)
self.panel.SetSizer(main_vbox)
self.Centre()
self.Show(True)
def add(self,event):
self.vbox.Add((wx.Button(self.panel,-1,"Button")))
if __name__ == "__main__":
app = wx.App()
MainWindow(None, -1, 'Add a Button')
app.MainLoop()
My problem is, the button gets added on top of the previous button. I'm rather mystified by this, because if I delete the event argument of the add() function, and then call it in the __init__ method, self.add(), it works fine. But that doesn't help me any because I need to add the widgets when the user clicks the button.
Any help is much appreciated.
Call self.panel.Layout() after adding the button. This function is called automatically when you resize a window with children (try it with your current code), but not when you add widgets to it.
I have a wxPython notebook, in this case a wx.aui.AuiNotebook. (but this problem has happened with other kinds of notebooks as well.) In my notebook I have a widget, in this case a subclass of ScrolledPanel, for which I am trying to do some custom event handling (for wx.EVT_KEY_DOWN). However, the events are not being handled. I checked my code outside of the notebook, and the event handling works, but when I put my widget in the notebook, the event handler doesn't seem to get invoked when the event happens.
Does the notebook somehow block the event? How do I solve this?
I tried reproducing your problem but it worked fine for me. The only thing I can think of is that there is one of your classes that also binds to wx.EVT_KEY_DOWN and doesn't call wx.Event.Skip() in its callback. That would prevent further handling of the event. If your scrolled panel happens to be downstream of such an object in the sequence of event handlers it will never see the event.
For reference, here's an example that worked for me (on Windows). Is what you're doing much different than this?
import wx
import wx.aui, wx.lib.scrolledpanel
class AppFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
# The notebook
self.nb = wx.aui.AuiNotebook(self)
# Create a scrolled panel
panel = wx.lib.scrolledpanel.ScrolledPanel(self, -1)
panel.SetupScrolling()
self.add_panel(panel, 'Scrolled Panel')
# Create a normal panel
panel = wx.Panel(self, -1)
self.add_panel(panel, 'Simple Panel')
# Set the notebook on the frame
self.sizer = wx.BoxSizer()
self.sizer.Add(self.nb, 1, wx.EXPAND)
self.SetSizer(self.sizer)
# Status bar to display the key code of what was typed
self.sb = self.CreateStatusBar()
def add_panel(self, panel, name):
panel.Bind(wx.EVT_KEY_DOWN, self.on_key)
self.nb.AddPage(panel, name)
def on_key(self, event):
self.sb.SetStatusText("key: %d [%d]" % (event.GetKeyCode(), event.GetTimestamp()))
event.Skip()
class TestApp(wx.App):
def OnInit(self):
frame = AppFrame(None, -1, 'Click on a panel and hit a key')
frame.Show()
self.SetTopWindow(frame)
return 1
if __name__ == "__main__":
app = TestApp(0)
app.MainLoop()