Retrive date from DateTimeCtrl WXPython - python-3.x

Hey all im having a difficult time with something I believe should be rather simple. Im using WXpython(3.X) to make my GUI and i'm using DatePickerCtrl to form my control. All im trying to do is retrieve the value when I change it. I used the GetValue() method but that only returns the date that currently shows not the one that I changed it to. Then I tried using DateEvent.GetDate but I keep getting an error.
def getStartDate(self):
a = wx.adv.DateEvent(self, self.date_Begin.GetValue(), Event.SetTimestamp()).GetDate
print(a)
return a
and the error that shows up is
**Event.SetTimestamp(): first argument of unbound method must have type 'Event'**

You have declared def getStartDate(self): rather than def getStartDate(self,event):, so you aren't allowing for the event sent to the function.
There is only one event emitted by this function EVT_DATE_CHANGED.
import wx
import datetime
import wx.adv
#----------------------------------------------------------------------
class TestPanel(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
dpc1 = wx.adv.DatePickerCtrl( self, wx.ID_ANY, wx.DefaultDateTime)
self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged, dpc1)
sizer.Add(dpc1, 0, wx.ALL, 50)
# In some cases the widget used above will be a native date
# picker, so show the generic one too.
dpc2 = wx.adv.GenericDatePickerCtrl(self, size=(120,-1),
style = wx.TAB_TRAVERSAL
| wx.adv.DP_DROPDOWN
| wx.adv.DP_SHOWCENTURY
| wx.adv.DP_ALLOWNONE )
self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged, dpc2)
sizer.Add(dpc2, 0, wx.LEFT, 50)
now = wx.DateTime.Now()
print (wx.DateTime.FormatISODate(now))
print (wx.DateTime.Format(now))
dpc2.SetValue(wx.DateTime.Now())
def OnDateChanged(self, evt):
sel_date = evt.GetDate()
print (sel_date.Format("%d-%m-%Y"))
#----------------------------------------------------------------------
if __name__ == '__main__':
app = wx.App()
frame = TestPanel()
frame.Show()
app.MainLoop()
Above I reformat the date to dd/mm/yyyy, as I am not from the USA.
If you want more control use wx.adv.CalendarCtrl

You should be able to bind your DatePickerCtrl widget to wx.adv.EVT_DATE_CHANGED
Then in your event handler, you would do something like this:
def OnDateChanged(self, evt):
new_date = evt.GetDate()
print(new_date)
return new_date
Check out the wxPython demo as it has a good example of this widget as well as most of the others.

Related

What is the right way to create multiple wx.AcceleratorEntry() entries and bind functions to them? wxPython

currently I'm working on my wxPython final High school project and I am facing another problem
I would like to bind keystroke combination entries (for example CTRL+S...) to my functions, but I can not achieve the result that would fulfill my expectations.
I've tried this, but the keystrokes were not bound.
accelnum = 2
accelerators = [wx.AcceleratorEntry() for x in range(accelnum)]
accelerators[0].Set(wx.ACCEL_CTRL, ord('S'), 'save')
accelerators[1].Set(wx.ACCEL_CTRL, ord('E'), 'export')
accel=wx.AcceleratorTable(accelerators)
self.SetAcceleratorTable(accel)
def save(self, event):
# some code...
def export(self, event):
# some other code...
I also tried to set ID to the same ID like i set to my toolbar tools but it says
that 'id' is not valid argument here.
Thank you very much for for all the advices. R
EDIT
For all wondering what could be wrong, I also used wx.EVT_CHAR_HOOK to detect "DEL" key. When I was rewriting my class second time, I forgot to add EVT_CHAR_HOOK and it worked. Until I added that EVT_CHAR_HOOK back. That means You can not use it simultaneously. So what I did next:
ID_SAVE = wx.NewIdRef()
ID_EXPORT = wx.NewIdRef()
ID_DELETE = wx.NewIdRef()
accelerators = [wx.AcceleratorEntry() for x in range(3)]
accelerators[0].Set(wx.ACCEL_CTRL, ord('S'), ID_SAVE)
accelerators[1].Set(wx.ACCEL_CTRL, ord('E'), ID_EXPORT)
accelerators[2].Set(wx.ACCEL_NORMAL, wx.WXK_DELETE, ID_DELETE)
to assign also my delete button and it works now
See: https://docs.wxpython.org/wx.AcceleratorEntry.html#wx.AcceleratorEntry.Set
The 3rd parameter to Set is should be the ID to be used when the event is created and sent. So you'll want to do it something like this instead:
ID_SAVE = wx.NewIdRef()
accelerators[0].Set(wx.ACCEL_CTRL, ord('S'), ID_SAVE)
When that key is pressed then an EVT_MENU event is sent, so you'll also need to bind a handler for it, like this:
self.Bind(wx.EVT_MENU, self.save, id=ID_SAVE)
Robin's answer, as always, does indeed work.
You may wish to check, exactly how you are implementing it.
Try something like this:
import wx
ID_SAVE = wx.NewIdRef()
ID_EXPORT = wx.NewIdRef()
accelerators = [wx.AcceleratorEntry() for x in range(2)]
accelerators[0].Set(wx.ACCEL_CTRL, ord('S'), ID_SAVE)
accelerators[1].Set(wx.ACCEL_CTRL, ord('E'), ID_EXPORT)
class MyFrame(wx.Frame):
def __init__(self, parent, id=wx.ID_ANY, title="", size=(360,100)):
super(MyFrame, self).__init__(parent, id, title, size)
accel=wx.AcceleratorTable(accelerators)
self.SetAcceleratorTable(accel)
self.panel = wx.Panel(self)
self.Bind(wx.EVT_MENU, self.OnSave, id=ID_SAVE)
self.Bind(wx.EVT_MENU, self.OnExport, id=ID_EXPORT)
self.Show()
def OnSave(self, event):
print("Save")
event.Skip()
def OnExport(self, event):
print("Export")
event.Skip()
if __name__ == "__main__":
app = wx.App()
frame = MyFrame(None,title="An Accelerator Test")
app.MainLoop()
The other answers already explain the 'how to'. Maybe this example can make coding somewhat easier for new readers.
As you can read in the other answers creating an accelerator needs 3 steps: 1) create an id, 2) create an accelerator and 3) bind to EVT_MENU. It took me some time to get it working myself.
So after 'getting the right way' I created a way to make it easier for me, "the easier way", when using a lot of accelerators by defining them in one place.
self._accelerators = {
wx.NewIdRef(): {'text': 'Previous Page (PageUp)',
'flags': wx.ACCEL_NORMAL,
'keyCode': wx.WXK_PAGEUP,
'handler': self.on_previous},
wx.NewIdRef(): {'text': 'Next Page (PageDown)',
'flags': wx.ACCEL_NORMAL,
'keyCode': wx.WXK_PAGEDOWN,
'handler': self.on_next},
wx.NewIdRef(): {'text': 'Select All (Ctrl+A)',
'flags': wx.ACCEL_CTRL,
'keyCode': ord('a'),
'handler': self.on_select_all},
}
And then let python do the boring stuff.
# ------------------------------------------------------------------------------------------------------------------
def _create_accelerators(self):
entries = []
for event_id, accelerator in self._accelerators.items():
# create the accelerator ---------------------------------------------
entry = wx.AcceleratorEntry(accelerator['flags'], accelerator['keyCode'], event_id)
entries.append(entry)
# bind handler to EVT_MENU ----------------------------------------
self.Bind(wx.EVT_MENU, accelerator['handler'], id=event_id)
accel_tbl = wx.AcceleratorTable(entries)
self.SetAcceleratorTable(accel_tbl)
A complete working example.
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Accelerator Test", size=(500, 500))
panel = wx.Panel(self, wx.ID_ANY)
# define the accelerators ---------------------------------------------
self._accelerators = {
wx.NewIdRef(): {'text': 'Previous Page (PageUp)',
'flags': wx.ACCEL_NORMAL,
'keyCode': wx.WXK_PAGEUP,
'handler': self.on_previous},
wx.NewIdRef(): {'text': 'Next Page (PageDown)',
'flags': wx.ACCEL_NORMAL,
'keyCode': wx.WXK_PAGEDOWN,
'handler': self.on_next},
wx.NewIdRef(): {'text': 'Select All (Ctrl+A)',
'flags': wx.ACCEL_CTRL,
'keyCode': ord('a'),
'handler': self.on_select_all},
}
# create the accelerators ---------------------------
self._create_accelerators()
# ----------------------------------------------------------------------
def _create_accelerators(self):
entries = []
for event_id, accelerator in self._accelerators.items():
# create the accelerator ---------------------------------------------
entry = wx.AcceleratorEntry(accelerator['flags'], accelerator['keyCode'], event_id)
entries.append(entry)
# bind handler to EVT_MENU ----------------------------------------
self.Bind(wx.EVT_MENU, accelerator['handler'], id=event_id)
accel_tbl = wx.AcceleratorTable(entries)
self.SetAcceleratorTable(accel_tbl)
# -------------------------------------------------------------------------------
def on_previous(self, event):
print(f"You pressed {self._accelerators[event.GetId()]['text']}")
# -------------------------------------------------------------------------------
def on_next(self, event):
print(f"You pressed {self._accelerators[event.GetId()]['text']}")
# -------------------------------------------------------------------------------
def on_select_all(self, event):
print(f"You pressed {self._accelerators[event.GetId()]['text']}")
# ===================================================================================
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
Some output.
You pressed Next Page (PageDown)
You pressed Previous Page (PageUp)
You pressed Select All (Ctrl+A)

Python - AutoComplete in an Editable Gtk.TreeView Cell

I was recently coding PyQt with a QComboBox in a QTable. The QComboBox has autocomplete on by default.
I was wanting to try and reproduce this in Python3 with Gtk3. I came across this example:
Gtk.Entry in Gtk.TreeView (CellRenderer)
that seems to have successfully added an autocompletion to a ComboBox in a Treeview. The example is not complete and I was hoping someone could give me a complete working example. I don't know how I 'connect' the CellRendererAutoComplete class to one of the columns in a treeview.
What I really want is to have AutoCompletion in an editable TreeView cell (with or without a ComboBox), but I have never come across this in the past in Gtk.
Thank you.
Here is a code example:
# https://stackoverflow.com/questions/13756787/
# https://python-gtk-3-tutorial.readthedocs.io/en/latest/cellrenderers.html
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
#######################################################################
class CellRendererAutoComplete(Gtk.CellRendererText):
""" Text entry cell which accepts a Gtk.EntryCompletion object """
__gtype_name__ = 'CellRendererAutoComplete'
def __init__(self, completion):
self.completion = completion
Gtk.CellRendererText.__init__(self)
def do_start_editing(
self, event, treeview, path, background_area, cell_area, flags):
if not self.get_property('editable'):
return
entry = Gtk.Entry()
entry.set_completion(self.completion)
entry.connect('editing-done', self.editing_done, path)
entry.show()
entry.grab_focus()
return entry
def editing_done(self, entry, path):
self.emit('edited', path, entry.get_text())
#######################################################################
class CellRendererTextWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererText Example")
self.set_default_size(200, 200)
self.liststore = Gtk.ListStore(str, str)
self.liststore.append(["Fedora", "http://fedoraproject.org/"])
self.liststore.append(["Slackware", "http://www.slackware.com/"])
self.liststore.append(["Sidux", "http://sidux.com/"])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_editabletext = Gtk.CellRendererText()
renderer_editabletext.set_property("editable", True)
########
# This is the problem area, I suppose, but I'm not sure
x = CellRendererAutoComplete()
renderer_editabletext.connect('on_edit',x(renderer_editabletext))
########
column_editabletext = Gtk.TreeViewColumn("Editable Text",renderer_editabletext, text=1)
treeview.append_column(column_editabletext)
renderer_editabletext.connect("edited", self.text_edited)
self.add(treeview)
def text_edited(self, widget, path, text):
self.liststore[path][1] = text
win = CellRendererTextWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
So here is an example showing a CellRendererText and a CellRendererCombo using an EntryCompletion.
Because of the complexity of the Treeview, where one ListStore can be the model behind the Completion, Combo, and Entry, and another model can be behind the Treeview, you should have a very good grasp of Gtk.Treeview to understand this example. Note that this example only uses one Liststore, and only one editable column used by both the CellRendererText and the CellRendererColumn. This makes the example confusing, but it the simplest I can come up with since I do not know the intended use for this Treeview.
#!/usr/bin/python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class CellRendererTextWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererText Example")
self.set_default_size(200, 200)
self.liststore = Gtk.ListStore(str, str)
self.liststore.append(["Fedora", "http://fedoraproject.org/"])
self.liststore.append(["Slackware", "http://www.slackware.com/"])
self.liststore.append(["Sidux", "http://sidux.com/"])
treeview = Gtk.TreeView(model=self.liststore)
self.completion = Gtk.EntryCompletion(model = self.liststore)
self.completion.set_text_column(1)
self.completion.connect('match-selected', self.renderer_match_selected)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
######## CellRendererText with EntryCompletion example
renderer_text = Gtk.CellRendererText()
renderer_text.connect('editing-started', self.renderer_text_editing_started)
renderer_text.connect('edited', self.text_edited)
renderer_text.set_property("editable", True)
column_text_autocomplete = Gtk.TreeViewColumn("Editable Text", renderer_text, text=1)
treeview.append_column(column_text_autocomplete)
######## CellRendererCombo with EntryCompletion example
renderer_combo = Gtk.CellRendererCombo(model = self.liststore)
renderer_combo.set_property("text-column", 1)
renderer_combo.connect('editing-started', self.renderer_combo_editing_started)
renderer_combo.connect('changed', self.combo_changed)
renderer_combo.set_property("editable", True)
column_combo_autocomplete = Gtk.TreeViewColumn("Editable Combo", renderer_combo, text=1)
treeview.append_column(column_combo_autocomplete)
self.add(treeview)
def renderer_match_selected (self, completion, model, tree_iter):
''' beware ! the model and tree_iter passed in here are the model from the
EntryCompletion, which may or may not be the same as the model of the Treeview '''
text_match = model[tree_iter][1]
self.liststore[self.path][1] = text_match
def renderer_text_editing_started (self, renderer, editable, path):
''' since the editable widget gets created for every edit, we need to
connect the completion to every editable upon creation '''
editable.set_completion(self.completion)
self.path = path # save the path for later usage
def text_edited(self, widget, path, text):
self.liststore[path][1] = text
def renderer_combo_editing_started (self, renderer, combo, path):
''' since the editable widget gets created for every edit, we need to
connect the completion to every editable upon creation '''
editable = combo.get_child() # get the entry of the combobox
editable.set_completion(self.completion)
self.path = path # save the path for later usage
def combo_changed (self, combo, path, tree_iter):
''' the path is from the treeview and the tree_iter is from the model
of the combobox which may or may not be the same model as the treeview'''
combo_model = combo.get_property('model')
text = combo_model[tree_iter][1]
self.liststore[path][1] = text
win = CellRendererTextWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
In the official docs, it is explicitly stated that the purpose of editing-started is to add a EntryCompletion and etc. I also subclassed Gtk.CellRendererText before I found that little hint in the docs.

PyQt - QCombobox in QTableview

I am displaying data from an SQLite database in a QTableView using a QSqlTableModel. Letting the user edit this data works fine. However, for some columns I want to use QComboboxes instead of free text cells, to restrict the list of possible answers.
I have found this SO answer and am trying to implement it on my model/view setting, but I'm running into problems (so this is a follow-up).
Here's a full mini-example:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5 import QtSql
from PyQt5.QtWidgets import (QWidget, QTableView, QApplication, QHBoxLayout,
QItemDelegate, QComboBox)
from PyQt5.QtCore import pyqtSlot
import sys
class ComboDelegate(QItemDelegate):
"""
A delegate that places a fully functioning QComboBox in every
cell of the column to which it's applied
source: https://gist.github.com/Riateche/5984815
"""
def __init__(self, parent, items):
self.items = items
QItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
combo = QComboBox(parent)
li = []
for item in self.items:
li.append(item)
combo.addItems(li)
combo.currentIndexChanged.connect(self.currentIndexChanged)
return combo
def setEditorData(self, editor, index):
editor.blockSignals(True)
# editor.setCurrentIndex(int(index.model().data(index))) #from original code
editor.setCurrentIndex(index.row()) # replacement
editor.blockSignals(False)
def setModelData(self, editor, model, index):
model.setData(index, editor.currentIndex())
#pyqtSlot()
def currentIndexChanged(self):
self.commitData.emit(self.sender())
class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(400, 150)
self.createConnection()
self.fillTable() # comment out to skip re-creating the SQL table
self.createModel()
self.initUI()
def createConnection(self):
self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("test.db")
if not self.db.open():
print("Cannot establish a database connection")
return False
def fillTable(self):
self.db.transaction()
q = QtSql.QSqlQuery()
q.exec_("DROP TABLE IF EXISTS Cars;")
q.exec_("CREATE TABLE Cars (Company TEXT, Model TEXT, Year NUMBER);")
q.exec_("INSERT INTO Cars VALUES ('Honda', 'Civic', 2009);")
q.exec_("INSERT INTO Cars VALUES ('VW', 'Golf', 2013);")
q.exec_("INSERT INTO Cars VALUES ('VW', 'Polo', 1999);")
self.db.commit()
def createModel(self):
self.model = QtSql.QSqlTableModel()
self.model.setTable("Cars")
self.model.select()
def initUI(self):
layout = QHBoxLayout()
self.setLayout(layout)
view = QTableView()
layout.addWidget(view)
view.setModel(self.model)
view.setItemDelegateForColumn(0, ComboDelegate(self, ["VW", "Honda"]))
for row in range(0, self.model.rowCount()):
view.openPersistentEditor(self.model.index(row, 0))
def closeEvent(self, e):
for row in range(self.model.rowCount()):
print("row {}: company = {}".format(row, self.model.data(self.model.index(row, 0))))
if (self.db.open()):
self.db.close()
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
In this case, I want to use a QCombobox on the "Company" column. It should be displayed all the time, so I'm calling openPersistentEditor.
Problem 1: default values I would expect that this shows the non-edited field's content when not edited (i.e. the company as it is listed in the model), but instead it apparently shows the ith element of the combobox's choices.
How can I make each combobox show the model's actual content for this field by default?
Problem 2: editing When you comment out "self.fill_table()" you can check whether the edits arrive in the SQL database. I would expect that choosing any field in the dropdown list would replace the original value. But (a) I have to make every choice twice (the first time, the value displayed in the cell remains the same), and (b) the data appears in the model weirdly (changing the first column to 'VW', 'Honda', 'Honda' results in ('1', 'VW', '1' in the model). I think this is because the code uses editor.currentIndex() in the delegate's setModelData, but I have not found a way to use the editor's content instead. How can I make the code report the user's choices correctly back to the model? (And how do I make this work on first click, instead of needing 2 clicks?)
Any help greatly appreciated. (I have read the documentation on QAbstractItemDelegate, but I don't find it particularly helpful.)
Found the solution with the help of the book Rapid GUI Programming with Python and Qt:
createEditor and setEditorData do not work as I expected (I was misguided because the example code looked like it was using the text content but instead was dealing with index numbers). Instead, they should look like this:
def setEditorData(self, editor, index):
editor.blockSignals(True)
text = index.model().data(index, Qt.DisplayRole)
try:
i = self.items.index(text)
except ValueError:
i = 0
editor.setCurrentIndex(i)
editor.blockSignals(False)
def setModelData(self, editor, model, index):
model.setData(index, editor.currentText())
I hope this helps someone down the line.

wxPython Panel Text Not Rendering

The problem I'm having is that when I set the static text inside a panel (see #Case 2) it only renders the first letter. The code below is a super stripped down version of my actual code but it produces an identical result:
import wx
import time
class TestInterface(wx.Frame):
testStatusFlag = 0
def __init__(self, *args, **kw):
super(TestInterface, self).__init__(*args, **kw)
self.pnl = wx.Panel(self)
self.SetSize((450, 225))
self.SetTitle('example')
self.Centre()
self.Show(True)
self.indicatorFullTest = None
self.buttonFullTest = None
self.setTestStatus(status=1)
def runTest(self, ev=None):
self.setTestStatus(status=2)
#the test is a bunch of functions that take a bunch of time to run
#they're all located in separate files but all access a single piece of hardware
#so multithreading is effectively impossible (I don't want to spend days re-writing stuff to accomodate it)
time.sleep(10)
self.setTestStatus(status=3)
return 0
def setTestStatus(self, ev=None, status=None):
#Handle the optional status argument
if (status in [1,2,3]):
self.testStatusFlag = status
#Remove any old stuff since if we're calling this function they have to get removed
if (self.indicatorFullTest != None):
self.indicatorFullTest.Hide()
if (self.buttonFullTest != None):
self.buttonFullTest.Hide()
#Case 1
if (self.testStatusFlag == 1):
self.buttonFullTest = wx.Button( self.pnl, label='Run Test', pos=(125, 100), size=(250, 50))
self.buttonFullTest.Bind(wx.EVT_BUTTON, self.runTest)
#Case 2
elif (self.testStatusFlag == 2):
self.indicatorFullTest = wx.Panel( self.pnl, pos=(125, 100), size=(250, 50))
wx.StaticText(self.indicatorFullTest, wx.ID_ANY, "Full-Board Test now in progress\nAllow up to 6 min to finish...",
style=wx.ALIGN_CENTRE_HORIZONTAL, pos=(18,7))
self.indicatorFullTest.SetBackgroundColour( 'Tan' )
self.Update()
#Case 3
elif (self.testStatusFlag == 3):
self.buttonFullTest = wx.Button( self.pnl, label='Test Complete\nPress to reset GUI',
pos=(125, 100), size=(250, 50) )
self.buttonFullTest.SetBackgroundColour( (130,255,130) )
self.buttonFullTest.Bind(wx.EVT_BUTTON, self.resetGUI)
#Resets the GUI after a test is complete
def resetGUI(self, ev=None):
self.setTestStatus(status=1) #Reset the fullTest button/indicator thing
if __name__ == '__main__':
ex = wx.App()
gui = TestInterface(None)
ex.MainLoop()
Basically, how do I make the UI fully render the text? I imagine it has something to do with not going back to wx's main loop after changing that indicator, but I feel like calling self.Update() should make that unnecessary. It may also have something to do with how I'm switching between using a button and using a panel (which is probably bad but I'm not sure how else to do it). I know that I could solve this by making my test function run in a separate thread but the problem is that the test function calls separate libraries which I literally do not have the time to re-write.
Thanks
This is a bit easier when you use wxPython's sizers because then you can just Show and Hide widgets. You can see a good example in this tutorial. I would recommend learning sizers just to make your UI more dynamic when you resize the frame.
But regardless, the answer to this conundrum is pretty simple. Instead of calling self.Update() in Case #2, you need to call wx.Yield(). I swapped that one line change in and it worked for me on Linux.

wx.webkit -- how to get current URL...?

I am trying to build a custom browser using wx.webkit. The following code works cleanly.
I want to get the current URL of the page that is being currently displayed. Using the GetPageURL() method does not seem to help. This always displays the starting URL (http://www.google.com in this case). It does not seem to get updated.
How can i get the updated URL when i navigate from one page to another...?
import wx
import wx.webkit
class wxBrowser(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(800, 625))
self.browser = wx.webkit.WebKitCtrl(self,-1)
self.browser.LoadURL('http://www.google.com')
self.browser.Bind(wx.EVT_KEY_DOWN, self.PrintURL)
self.Centre()
self.Show(True)
def PrintURL(self, event):
# show current URL on Cmd P
if event.CmdDown() and event.GetKeyCode() == 80:
print self.browser.GetPageURL()
if __name__ == '__main__':
app = wx.App()
wxBrowser(None, -1, 'My Browser')
app.MainLoop()
Use a wx.html2.WebView.New widget instead.
There is a get_uri() method. You have to use it like this
browser = webkit.WebView()
browser.open("http://example.com")
print browser.get_main_frame().get_uri()

Resources