3

I've seen another question regarding this topic, but I couldn't quite get the information to work for me, so I thought I'd give my specifics - I suspect I'm just being short-sighted.

I'm trying to exercise my GUI from a test framework, which involves manually invoking an event (in this case a button press) within a test script. So far, in addition to other irrelevant guff, I have:

# In GUI class:

self.button_1 = wx.Button(self, id=wx.ID_ANY, label="Button 1")
self.button_1.Bind(wx.EVT_BUTTON, self.button_1)

# In GUI Test class:

event = wx.PyCommandEvent(X, Y)
wx.PostEvent(get_gui_instance(), event)

My problem is that I don't know what X and Y should be (assuming that the rest is ok). Any help is greatly appreciated.

Community
  • 1
  • 1
Ed King
  • 1,833
  • 1
  • 15
  • 32

3 Answers3

5
btnInfo = wx.Button(self,-1,"Some Button")

evt = wx.PyCommandEvent(wx.EVT_BUTTON.typeId,btnInfo.GetId())
wx.PostEvent(self, evt)  #attach event to self ... alternatively maybe attach to btnInfo

should work

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Although this ran without error, it did not invoke the event. I'm running the GUI in its own thread and trying to communicate from a worker thread running GUI Test - would this be an issue? To change the value of some text boxes from GUI Test, I have already implemented my own event to do that (which works) - do I have to follow a similar approach here with button-presses? – Ed King Oct 09 '12 at 08:08
  • yes you cannot listen for events accross threadss afaik ... and make sure you use the right argument instead of self for the PostEvent ... post it to whatever is Bound to evt_button – Joran Beasley Oct 09 '12 at 14:20
1

So it turns out that because I've re-jigged my GUI to run in a worker thread from GUI Test, I can communicate with it directly. I should have realised this earlier, but nonetheless the result is that I don't need to bother with posting events from GUI Test to GUI since they're running in the same process.

Instead, I can now call the effects of events directly. For example, I can call on_button_press(), bypassing the actual clicking of the button, which would normally fire off the event in wxPython. This allows me to simulate user interaction and test workflows and input ranges, which is exactly what I wanted to do.

Of course, this only works because I'm running my GUI in the same process as the test suite. Posting events seems to be the way forward otherwise, and in answer to my own question, it seems custom events are the way to invoke button presses cross-process. This implies the use of some sort of "test agent" within the GUI to handle those events that are specific for testing.

Ed King
  • 1,833
  • 1
  • 15
  • 32
0
import wx

class MessageDialog(wx.Dialog):
    def __init__(self, message, title, tiempo = 2000):

        style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
        super(MessageDialog, self).__init__(None, -1, title, style=style)
        text = wx.StaticText(self, -1, message)

        fuente = wx.Font(pointSize = 20, 
                     family = wx.DEFAULT, 
                     style = wx.NORMAL, 
                     weight = wx.LIGHT, 
                     underline=False, 
                     faceName="", 
                     encoding=wx.FONTENCODING_DEFAULT)        
        text.SetFont(fuente)




        self.ok = wx.Button(self, wx.ID_OK, "OK")
        sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(text,0,wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL,5)
        sizer.Add(self.ok, 0, wx.EXPAND|wx.ALL, 5)
        self.SetSizerAndFit(sizer)
        color = "WHEAT"
        self.SetBackgroundColour(color)
        self.Center()
        self.Refresh()
        wx.FutureCall(tiempo,self.salir_ok)

    def salir_ok(self):
        par_btn = getattr(self, "ok")
        evt = wx.PyCommandEvent(wx.EVT_BUTTON.typeId, par_btn.GetId())
        wx.PostEvent(self, evt)
        return

if __name__ == '__main__':
    app = wx.App()
    dialog = MessageDialog( 'Teclee el nombre del proveedor', 'Proveedor')

    dialog.ShowModal()
    dialog.Destroy()
    app.MainLoop()