How do I create a frame with extra style information

The wx.frame_ex_contexthelp style is an extended style, which means that the value of its flag is too large to be set using the normal constructor (because of the specific limitations of the underlying C + + variable type). Normally you can set extra styles after the widget has been created using the SetExtraStyle method, but some styles, such as wx.frame_ex_contexthelp, must be set before the native UI object is created. In wxPython, this needs to be done using a slightly awkward method known as two-step construction. After using this construction, a frame is created with the familiar question mark icon in the title bar, as displayed in figure 8.4.

The flag value has to be set using the method SetExtraStyle(). Sometimes the extra style information must be set before the frame is instantiated, leading to the philosophical question of how you can call a method on an instance that does not yet exist. In the next sections, we'll show two mechanisms for performing this operation, with the second being a generic abstraction of the first.

Adding extra style information

In wxPython, extra style information is added before creation by using the special class wx.PreFrame, which is a kind of partial instance of a frame. You can set the extra style bit on the preframe, and then create the actual frame instance using the preframe. Listing 8.3 displays how two-step construction is done in a subclass constructor. Notice that it's actually a three-step process in wxPython (in the C + + wxWidgets toolkit, it is a two-step process, hence the name).

Listing 8.3 A two-stage window creation import wx class HelpFrame(wx.Frame):

def _init_(self): A The pre-construction object pre = wx.PreFrame()

pre.SetExtraStyle(wx.FRAME_EX_CONTEXTHELP) pre.Create(None, -1, "Help Context", size=(300, 100), style=wx.DEFAULT_FRAME_STYLE *

Figure 8.4 A frame with the extended context help enabled

Figure 8.4 A frame with the extended context help enabled

(wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX)) self.PostCreate(pre) <1—i

I Transfer of underlying if _name_ == '_main_': © C+ + pointers app = wx.PySimpleApp()

HelpFrame().Show()

app.MainLoop()

This call creates the frame

O Create an instance of wx.PreFrame() (for dialog boxes, there's an analogous wx.PreDialog()—other wxWidgets widgets have their own preclasses). After this call, you can do whatever other initialization you need. C Call the Create() method, which has the same signature as the wxPython constructor.

© This is the wxPython-specific line and is not done in C + + . The PostCreate method does some internal housekeeping that makes your wxPython instance a wrapper around the C + + object you created in the first step.

Adding extra style information generically

The algorithm given earlier is a bit awkward, but it can be refactored into something a little easier to manage. The first step is to create a generic utility function that can manage any two-step creation. Listing 8.4 provides an example using Python's reflective ability to call arbitrary functions passed as variables. This example is meant to be called in the_init_method during the Python instantiation of a new frame.

Listing 8.4 A generic two-step creation function def twoStepCreate(instance, preClass, preInitFunc, *args, **kwargs): pre = preClass() preInitFunc(pre) pre.Create(*args, **kwargs) instance.PostCreate(pre)

In listing 8.4, the function takes three required arguments. The instance argument is the actual instance being created. The preClass argument is the class object for the temporary preclass—for frames it is wx.PreFrame. The preInitFunc is a function object that would generally be a callback to an initialization method of the instance. After that, an arbitrary number of other optional arguments can be added.

The first line of the function, pre = preClass(), reflectively instantiates the pre-creation object, using the class object passed as an argument. The next line reflectively calls the callback function passed to the preInitFunc—in this context, that would usually set the extended style flag. Then the pre.Create() method is called, using the optional arguments. Finally, the PostCreate method is called to transplant internal values from pre to instance. At that point, the instance argument has been fully created. Assuming that twoStepCreate is imported, the utility function could be used as in listing 8.5.

Listing 8.5 Another two-step creation, using the generic method import wx class HelpFrame(wx.Frame):

def _init_(self, parent, ID, title, pos=wx.DefaultPosition, size=(100,100), style=wx.DEFAULT_DIALOG_STYLE): twoStepCreate(self, wx.PreFrame, self.prelnit, parent, id, title, pos, size, style)

def preInit(self, pre):

pre.SetExtraStyle(wx.FRAME_EX_CONTEXTHELP)

The class wx.PreFrame, and the function self.prelnit are passed to the generic function, and the preInit method is defined as the callback.

Was this article helpful?

0 0

Responses

  • Camilla Panicucci
    What is twostep frame construction?
    8 years ago

Post a comment