I am not sure what they are called, but I would like a resizable divider line, to separate widgets.
I would like something like this (except horizontal):
http://imm.io/bKgf
If you do not know what i am talking about please comment, thanks and sorry for my ignorance.
You need, maybe, a splitterwindow:
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.splitter = wx.SplitterWindow(self)
pan1 = wx.Window(self.splitter, style=wx.BORDER_SUNKEN)
pan1.SetBackgroundColour("yellow")
wx.StaticText(pan1, -1, "My Left Panel")
pan2 = wx.Window(self.splitter, style=wx.BORDER_SUNKEN)
pan2.SetBackgroundColour("orange")
wx.StaticText(pan2, -1, "my Right Panel")
self.splitter.SplitVertically(pan1, pan2, -100)
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MyFrame(None)
frame.Show()
app.MainLoop()
I'm not sure if this will exactly meet your needs, but you might have a look at wxPython's aui module. There's some demo code on that page that'll get you started, and the wxPython demo has some good examples to try out.
What you want is wx.StaticLine. Just create one of those and add it to your sizer with the EXPAND style flag. See http://www.wxpython.org/docs/api/wx.StaticLine-class.html for more info.
EDIT: Oh, I think Joaquin's suggestion for a SplitterWindow may be spot on. Note that there a couple other types of SplitterWindows, like MultiSplitterWindow and FourWaySplitter
Related
Introduction and Issue
I've made a gridsizer to resize my frame itself.
But because of the gridsizer if I use WX_EXPAND flag (to let them have a new height and width when I use self.Layout() to refresh when the app is resized) they don't resize the % of the screen I gave them (I put blank widget to put all my widget where I want).
Example here
What I have tried
I've tried to make a wx.GridBagSizer but I can't understand why it always say that GenericTreeCtrl don't exist (its a must I need this tree) so I'm asking a way to do this with wx.GridSizer.
I want to work with something like that and be able to resize my widget: what I want to be resizable
Question
Can you please tell me whats the correct and optimal way to dynamically resize a widget using a wx.GridSizer?
class mainPanel(wx.Panel):
def __init__(self, parent, pageNum, FrameSize):
self.parent = parent
self.pageNum = pageNum
wx.Panel.__init__(self, parent=parent)
Sizer = wx.GridSizer(6,6,0,0)
self.PathList = []
self.PathSelected = []
self.pastePath = ""
self.SetSizer(Sizer)
#tree
widthA,heightA = FrameSize[0],FrameSize[1]
path = "/media/" + os.getlogin()
self.folder_tree_project = wx.GenericDirCtrl(self, wx.ID_ANY,path, (0,0), wx.Size(widthA*0.3,heightA*0.75),wx.FULL_REPAINT_ON_RESIZE|wx.DIRCTRL_MULTIPLE)
Sizer.Add(self.folder_tree_project,0,wx.LEFT,0)
self.t1 = self.folder_tree_project.GetTreeCtrl()
self.folder_tree_project.ShowHidden(False)
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelect,id=self.t1.GetId())
self.Bind(wx.EVT_SIZE, self.OnResize)
#--------------------------------------------------------
def OnResize(self,event):
FrameSize = self.GetSize()
self.Sizer.Layout()
Try this
def OnResize(self,event):
FrameSize = self.GetSize()
widthA,heightA = FrameSize[0],FrameSize[1]
self.folder_tree_project.SetSize((int(widthA*0.3),int(heightA*0.75)))
self.Sizer.Layout()
I will not be able to test it Leonardo but thanks for the reply ! (i did not answered because of the Global Game Jam that i was participating)
I've found another way thanks to someone on another forum, using the app 'WxGlade' I was able to understand how GridBagSizer work.
You can't do things like GenericDirCtrl in WxGlade but I've read the code given by it by putting button and blank text like I want and putting gridbagsizer, with the previsualization and the generated code I was able to understand how GridBagSizer work.
I'm trying to use the ThumbnailCtrl and I would like to change the background color.
I would have expected this code to work
self.thumbnail_ctrl.SetBackgroundColour('red')
Unfortunately it does not works and I ended hacking a solution show in the following minimal example in which I used the internal field _scrolled setting the background color on it.
I'm still a beginner and would like to ask if I did something wrong with the expected call show above.
#!/usr/bin/env python
import wx
import wx.lib.agw.thumbnailctrl as TC
class MyPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent=parent)
self.thumbnail_ctrl = TC.ThumbnailCtrl(parent=self, imagehandler=TC.NativeImageHandler)
self.thumbnail_ctrl.ShowFileNames(False) # do not show the filename under the thumbs
self.thumbnail_ctrl.SetThumbOutline(TC.THUMB_OUTLINE_RECT) # outline the rect
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
self.main_sizer.Add(window=self.thumbnail_ctrl, proportion=1, flag=wx.ALL|wx.EXPAND, border=0)
self.SetSizer(self.main_sizer)
# Hack to set the background color of self.thumbnail_ctrl
# self.thumbnail_ctrl.SetBackgroundColour('red') # Calling this does not works
self.thumbnail_ctrl._scrolled.SetBackgroundColour('red') # Calling this the background color is set to red
self.Refresh()
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='minimal set background example')
self.panel = MyPanel(parent=self)
self.Show()
if __name__ == '__main__':
app = wx.App(redirect=True)
frame = MyFrame()
app.MainLoop()
As far as I remember I haven’t put in any way to set the background color of Thumbnailctrl - I simply forgot I guess. So your solution, while of course a hack, it’s a perfectly valid one. You may want to open an issue or submit a PR to wxPython github so a proper SetBackgroundColour can be added to the class in the source.
Im making a python program and in some functions it needs to hide the X and expand window buttons, how would i do it? Im using WxPython, how would I put this in?
The widgets in the window frame are defined as part of the window's style: CLOSE_BOX, MINIMIZE_BOX, and MAXIMIZE_BOX.
So, when you create the window, just leave those styles out.
If you're using a wx.Frame subclass, note that DEFAULT_FRAME_STYLE includes these values, so you will have to mask them out:
style = wx.DEFAULT_FRAME_STYLE & (~wx.CLOSE_BOX) & (~wx.MAXIMIZE_BOX)
super().__init__(whatever, args, you, use, style=style)
If you want to change them after creation, you use SetWindowStyle:
style = self.GetWindowStyle()
self.SetWindowStyle(style & (~wx.CLOSE_BOX) & (~wx.MAXIMIZE_BOX))
self.Refresh()
However, notice that the documentation of that function says:
Please note that some styles cannot be changed after the window creation and that Refresh() might need to be called after changing the others for the change to take place immediately.
And, from what I can tell, on Windows, if you create a window with a close box and then remove it later in this way, it doesn't actually go away. It does disable, which may be good enough. But if not, there's probably no way to do what you want without either reaching underneath wx to the native Windows API (which gets very tricky), or drawing the widgets on the frame manually (which gets even more tricky, especially if you care about looking right on different versions of Windows—not to mention porting to other platforms).
I wrote about Frame styles a while ago on my blog. To remove all the buttons, you could do this:
import wx
########################################################################
class NoSystemMenuFrame(wx.Frame):
"""
There is no system menu, which means the title bar is there, but
no buttons and no menu when clicking the top left hand corner
of the frame
"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
no_sys_menu = wx.CAPTION
wx.Frame.__init__(self, None, title="No System Menu", style=no_sys_menu)
panel = wx.Panel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = NoSystemMenuFrame()
app.MainLoop()
I tried setting the style to wx.DEFAULT_FRAME_STYLE & (~wx.CLOSE_BOX) & (~wx.MAXIMIZE_BOX) and to wx.DEFAULT_FRAME_STYLE^(wx.CLOSE_BOX|wx.MAXIMIZE_BOX), but both of those seem to only remove the Close box. For some reason, the Maximize button is still there on my Xubuntu machine.
I'm trying to send colored text to a TextCtrl widget, but don't know how
style = wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2
self.status_area = wx.TextCtrl(self.panel, -1,
pos=(10, 270),style=style,
size=(380,150))
basically that snippet defines a status box in my window, and I want to write colored log messages to it. If I just do self.status_area.AppendText("blah") it will append text like I want, but it will always be black. I can't find the documentation on how to do this.
You need to call SetStyle to change the text behavior.
import wx
class F(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, None)
style = wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2
self.status_area = wx.TextCtrl(self, -1,
pos=(10, 270),style=style,
size=(380,150))
self.status_area.AppendText("blahblahhblah")
fg = wx.Colour(200,80,100)
at = wx.TextAttr(fg)
self.status_area.SetStyle(3, 5, at)
app = wx.PySimpleApp()
f = F()
f.Show()
app.MainLoop()
documentation of wxwidgets has this to say (you can also look up wxPython docs, but it points to wxwidgets anyway):
either use SetDefaultStyle before you append text to your textctrl, or after inserting text use SetStyle.
According to docs, the first solution is more efficient (and sounds easier to me.)
Im looking for a way to present a flexible font, that will increase and decrease in size according to to the size of the screen resolution. I want to be able to do this without the HTML window class. Is there a way? I thought I've done quite a bit of googling without success.
EDIT
This seems a good question, I changed the title to reflect closer what I was looking for.
EDIT
So now I've realized that the regular pixel sizes will scale in the way I mentioned already - but I saw this the other day and realized it might be helpful if someone wanted to use CSS with their wxPython Apps - its a library that allows you to 'skin' your application and I can think of a dozen neat ways to use it already - here is a link in lieu of a more well thought out question :)
link text
Maybe something like this? You can scale any wx.Window in this way. Not sure if this is exactly what you mean though.
import wx
def scale(widget, percentage):
font = widget.GetFont()
font.SetPointSize(int(font.GetPointSize() * percentage / 100.0))
widget.SetFont(font)
class Frame(wx.Frame):
def __init__(self):
super(Frame, self).__init__(None, -1, 'Scaling Fonts')
panel = wx.Panel(self, -1)
sizer = wx.BoxSizer(wx.VERTICAL)
for i in range(50, 201, 25):
widget = wx.StaticText(panel, -1, 'Scale Factor = %d' % i)
scale(widget, i)
sizer.Add(widget, 0, wx.ALL, 5)
panel.SetSizer(sizer)
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = Frame()
frame.Show()
app.MainLoop()