Skinnable/Stylable windows in wxPython?

D

Daniel Bickett

I'm very near finishing a medium to large scale application, so I'm
getting a head start on the GUI side of things. Part of the concept is
to give as much attention to presentation as functionality, and
something I really wanted to do was transcend the basic window and
style it to an extent,

To be honest, the wxPopupWindow was basically what I was looking for,
but it isn't available on Mac, eliminating that possibility.
wxShapedWindow would have sufficed, but it uses a more recent version
wxPython that I've chosen not to install for various dependency
issues, so I really can't use that.

I've combed through the demo countless times, but I really can't find
any answers. So, the question: what is the best way (or is there one,
rather) to achieve an end comparable to skinning my wx windows?

Thanks for your help,
Daniel Bickett
 
M

mefjr75

Hello Daniel,
The wxPopupWindow is also missing several things that would make it
suitable for a frame, like accelerator events. I built a 'chromeless'
picture viewer once using wxPopupWindow and it worked , but it was
missing things I needed because of missing functionality in
wxPopupWindow. IMHO is isn't intended to be used as a full featured
frame.
The only way *I* know how to skin an app in wxWindows is using
wxShapedWindow .wxShapedWindow just changes the frame shape, you then
need to render a background picture and then place elements on that
background for buttons and other controls, you also will have to
implement functionality for those elements so they work like normal
controls, plus a hundred other gotchas.
Skinning is a pain ,and to do it right you probably need to use a
'DoubleBufferedDc' so your elements won't flicker when you click or
move them. I started writing a generic skinner class that does the hard
stuff but when I tested found that it needed to be rewritten using a
DoubleBefferedDC. Maybe someday...
Hope any of this helps maybe others have diffrent ideas.
M.E.Farmer
 
D

Daniel Bickett

Solution found!

For the future reference of anyone searching:

The wxPopupWindow can easily be achieved by creating a wxMiniFrame
with absolutely no styles ('0', explicitly). The features of the
wxPopupWindow in the wxPython demo don't come with it, they were
manually added in the demo code, so simply adapting the code should
suffice.

Even as I was typing this message, I realized that this was probably
exactly what wxPopupWindow was, and suddenly this clicked because I
remembered seeing in the wxWindows help files that all of the styles
for wxMiniFrame only worked on Windows and Motif, and it made a point
to note that they didn't work on GTK. So I tried a snippet of code[1]
on my Mac (until then I had been working on a windows box) and, to my
surprise, it worked perfectly.

This raises some questions for me, like why, if the wxPython package
is going to have the wxPopupWindow feature, they don't simply inherit
wxMiniFrame like I did (quite literally, it looks /exactly/ the same
as a wxPopupWindow). Not only would this make it more multi-platform
(I have no access to a GTK machine so I don't know if this works.
Could someone please check?), but it would be more useful, considering
the fact that it is in fact a frame, and wouldn't have the problems
that M.E.Farmer outlined above regarding controls on wxPopupWindows.

Regardless, I'm happy that I've uncovered the answer, and I hope this
helps someone else in the same situation :)

Daniel Bickett

NOTES:
[1] from wxPython.wx import wxMiniFrame, wxPySimpleApp
app = wxPySimpleApp()
frame = wxMiniFrame( None , -1 , '' , size = ( 300 , 150 ) , style = 0 )
frame.Show()
app.MainLoop()
 
R

Roel Schroeven

Daniel said:
Solution found!

Not only would this make it more multi-platform (I have no access to
a GTK machine so I don't know if this works. Could someone please
check?)

Looks like it works (I had to change frame.Show() to frame.Show(1)
though, but that could be because it's an old version). One odd thing
though: the Windows version doesn't react to clicking or dragging the
mouse, which seems to be the expected behavior. The GTK version can be
moved by dragging the mouse; even just clicking the mouse moves the
window somewhat down and to the left.
 
D

Daniel Bickett

Not only would this make it more multi-platform (I have no access to
Looks like it works (I had to change frame.Show() to frame.Show(1)
though, but that could be because it's an old version).

No, I think that was a slip on my part when copying the code from one
screen to the next :)
One odd thing
though: the Windows version doesn't react to clicking or dragging the
mouse, which seems to be the expected behavior.

I noted in my second post that the functionality of the window
(clicking and dragging et al) was, even in the wxPopupWindow demo,
implemented by using the EVT macros. Copied from the demo, the code is
as follows:

def OnMouseLeftDown(self, evt):
self.ldPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
self.wPos = self.GetPosition()
self.CaptureMouse()

def OnMouseMotion(self, evt):
if evt.Dragging() and evt.LeftIsDown():
dPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
nPos = (self.wPos.x + (dPos.x - self.ldPos.x),
self.wPos.y + (dPos.y - self.ldPos.y))
self.Move(nPos)

def OnMouseLeftUp(self, evt):
self.ReleaseMouse()

def OnRightUp(self, evt):
self.Show(False)
self.Destroy()
The GTK version can be
moved by dragging the mouse; even just clicking the mouse moves the
window somewhat down and to the left.

That's interesting... I wonder if using those methods would conflict
at all. Also, while I'm on that note, when double clicking on the
resulting window (after binding those events), double click causes a
non-fatal, yet annoying, traceback saying that "the mouse could not be
released because it has not yet been caught blah blah", so I just
wrapped the contents of OnMouseLeftUp in a try..except..pass.

Daniel Bickett
 
R

Roel Schroeven

Daniel said:
No, I think that was a slip on my part when copying the code from one
screen to the next :)

I tried again with newer versions (Python 2.3 and wxPython 2.4); the
code runs as-is, without that modification.
That's interesting... I wonder if using those methods would conflict
at all.

I couldn't reproduce that behaviour this time. It might have had
something to do with the test setup the first time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top