wxPython: maximize Frame while disable resizing (Linux) - python

On Linux, how do you disable re-sizing, but at the same time maximize the interface to begin with?
I have tried the following but it is not maximized:
style = wx.DEFAULT_FRAME_STYLE & ~wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER)
style = wx.MAXIMIZE | wx.DEFAULT_FRAME_STYLE & ~wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER
EDIT:
Tried Maximize() with resize disabled, still nothing. My versions: Linux, Python 2.4, wxPython 2.8.12.1
(style = wx.MAXIMIZE works for Windows, but not for Linux)

You're pretty close. You just forgot to call Maximize(). See below:
import wx
########################################################################
class NoResizeFrame(wx.Frame):
"""
This frame cannot be resized. It can only be minimized, maximized
and closed
"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
wx.RESIZE_BOX |
wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, None, title="No Resize", style=no_resize)
panel = wx.Panel(self)
self.Show()
self.Maximize()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = NoResizeFrame()
app.MainLoop()
You might find this tutorial of mine useful for better understanding frame style flags:
http://www.blog.pythonlibrary.org/2013/11/06/wxpython-101-using-frame-styles/
Or this slightly older tutorial on maximizing:
http://www.blog.pythonlibrary.org/2013/07/12/wxpython-making-your-frame-maximize-or-full-screen/

Related

How to prevent user dragging window/frame

I need to create a simple app that cannot be resized, minimised, maximised and moved. I've been able to fulfill all this requirements but one thanks to this answer but I cant find how to prevent window dragging.
I've tried to adapt this C++ answer : when move event is trigerred, I just move back the window to its original position, but it's not very clean : it makes the windows shaky and sometimes minimize all other running apps. Also, the "Move" options is style available from system menu and I'd like to disable it.
So how can I disable dragging the window when clicking on title bar and disable Move option from system menu ?
I'm running Windows 10, Python 3.10 and wxpython 4.1.1.
def __init__(self):
# stuffs ...
self.Center()
self.Show()
x, y = self.GetPosition()
self.x = x
self.y = y
self.Bind(wx.EVT_MOVE, self.on_move)
def on_move(self, ev):
ev.Skip()
self.Move(self.x, self.y)
I would never recommend having a window that is not moveable but if that is a game changer, in your specific situation, then you could define a window that has no frame and thus is not moveable.
The downside is that you would have to include any caption and a close facilty within the window yourself.
I'd also recommend making it Always_on_top.
As you can see, you gain the restrictions but lose compatability with other windows on the desktop.
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, ("Moveable or Stuck"), size=(420, 210), \
style = wx.FRAME_NO_TASKBAR \
& ~(wx.MINIMIZE_BOX|wx.RESIZE_BORDER|wx.MAXIMIZE_BOX))
panel = wx.Panel(self)
caption = wx.StaticText(panel, -1, "Moveable or Stuck", pos=(10,5))
caption.SetBackgroundColour('lightgrey')
self.CloseButton = wx.BitmapButton(panel, bitmap=wx.ArtProvider.GetBitmap(wx.ART_CLOSE), \
pos=(380,5), size=(32,32))
self.Bind(wx.EVT_BUTTON, self.OnExit)
self.SetWindowStyle(wx.STAY_ON_TOP | wx.BORDER_NONE | wx.FRAME_NO_TASKBAR )
def OnExit(self, event):
self.Destroy()
app = wx.App()
frame = MyFrame(None)
frame.Show()
app.MainLoop()
I don't run windows OS so I can't test the wx.EVT_MOVE_END event, which should give you a better result.
The style gives you just a Close box and prevents the window being included in the taskbar.
Overriding the Move ability provided by the OS, is I believe, not possible, at an App level at least.
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, ("Moveable or Stuck"), size=(420, 210), \
style = wx.SYSTEM_MENU|wx.CLOSE_BOX|wx.FRAME_NO_TASKBAR \
& ~(wx.MINIMIZE_BOX|wx.RESIZE_BORDER|wx.MAXIMIZE_BOX))
self.Pos = self.GetPosition()
# other than Windows OS
self.Bind(wx.EVT_MOVE, self.OnMove)
# Windows Only
#self.Bind(wx.EVT_MOVE_END, self.OnMove)
def OnMove(self, event):
self.SetPosition(self.Pos)
app = wx.App()
frame = MyFrame(None)
frame.Show()
app.MainLoop()

wxPython - code highlighting and pygment

I am trying to utilize pygment for some code highlighting in a wxPython RichTextCtrl.
I can't find much online (other than broken links) about achieving this.
Here is some sample code. I've tried a few different formatters and they all fail. I believe editra using pygment and wxpython, but the source is difficult to navigate.
import wx
import wx.richtext
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters.rtf import RtfFormatter
lexer = get_lexer_by_name("python", stripall=True)
formatter = RtfFormatter()
code = """ # Comment
a = 5
print(a)
print(b)
"""
formatted_code = highlight(code, lexer, formatter)
########################################################################
class MyFrame(wx.Frame):
# ----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, title='Richtext Test')
sizer = wx.BoxSizer(wx.VERTICAL)
self.rt = wx.richtext.RichTextCtrl(self)
self.rt.SetMinSize((300, 200))
self.rt.ChangeValue(formatted_code)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.rt, 1, wx.EXPAND | wx.ALL, 6)
self.SetSizer(sizer)
self.Show()
# ----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Thanks for any help
I ended up using StyledTextCtrl as suggested in the comments. It turns out there are 2 demos included with the wxPython source, the 2nd of which does exactly what I was trying. I would post the code but it is ~400 lines.

Is a toolbar icon supposed to show?

I have the following code and I'm on OSX. However, I'm expecting to see a toolbar icon but I'm not seeing one. Am I doing something wrong or should it work on Windows? Here's the code
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
super(Example, self).__init__(parent, title=title,size=(400, 350))
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
self.panel = wx.Panel(self)
toolbar = wx.ToolBar(self, size=(-1, 128))
toolbar.SetToolBitmapSize((128,128))
bmp2 = wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, (128,128))
toolbar.AddLabelTool(-1, label="Add", bitmap=bmp2,
shortHelp="Add", kind=wx.ITEM_NORMAL)
toolbar.Realize()
self.SetToolBar(toolbar)
if __name__ == '__main__':
app = wx.App()
Example(None, title='')
app.MainLoop()
Thanks
The call to Realize needs to happen after the SetToolBar. This is because there are two different kinds of toolbars on OSX and which is chosen depends on if it is attached to a frame or not, and all that happens in the Realize call. Also, OSX is picky about the size of the tools, and the 128 you use will likely be reduced to a supported size.

WxPython and ShowMeDo tutorial

I was working through the third video in this tutorial series in my effort to learn WxPython. I typed the code as in the video but an error is still returned. I am guessing this has something to do with the WxPython or Python version used. He is using Python 2.4, I am using 2.7.5 and I don't know what WxPython version he is using but I am using 3.0.0.
This is the code:
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (400,200), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
self.control = wx.TextCtrl(self,1,style = wx.TE_MULTILINE)
self.Show(True)
app = wx.PySimpleApp()
frame = MainWindow(None,-1,"Small Editor")
app.MainLoop()
Invalid syntax is returned for self.control but I don't know why.
Any help is appreciated,
Fluffy
It looks like you're missing the final enclosing parenthesis on the line directly above.
Generally speaking, syntax errors are typically due to misspellings, missing characters, or other such mistakes, and can either be found on the line indicated by the stacktrace or the line directly above.
Once the parenthesis is added, the below code runs for me:
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (400,200), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.control = wx.TextCtrl(self,1,style = wx.TE_MULTILINE)
self.Show(True)
app = wx.PySimpleApp()
frame = MainWindow(None,-1,"Small Editor")
app.MainLoop()

Why is wxGridSizer much slower to initialize on a wxDialog then on a wxFrame?

It seems that this is specific to windows, here is an example that reproduces the effect:
import wx
def makegrid(window):
grid = wx.GridSizer(24, 10, 1, 1)
window.SetSizer(grid)
for i in xrange(240):
cell = wx.Panel(window)
cell.SetBackgroundColour(wx.Color(i, i, i))
grid.Add(cell, flag=wx.EXPAND)
class TestFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
makegrid(self)
class TestDialog(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent)
makegrid(self)
class Test(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
btn1 = wx.Button(self, label="Show Frame")
btn2 = wx.Button(self, label="Show Dialog")
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
sizer.Add(btn1, flag=wx.EXPAND)
sizer.Add(btn2, flag=wx.EXPAND)
btn1.Bind(wx.EVT_BUTTON, self.OnShowFrame)
btn2.Bind(wx.EVT_BUTTON, self.OnShowDialog)
def OnShowFrame(self, event):
TestFrame(self).Show()
def OnShowDialog(self, event):
TestDialog(self).ShowModal()
app = wx.PySimpleApp()
app.TopWindow = Test()
app.TopWindow.Show()
app.MainLoop()
I have tried this on the following configurations:
Windows 7 with Python 2.5.4 and wxPython 2.8.10.1
Windows XP with Python 2.5.2 and wxPython 2.8.7.1
Windows XP with Python 2.6.0 and wxPython 2.8.9.1
Ubuntu 9.04 with Python 2.6.2 and wxPython 2.8.9.1
The wxDialog wasn't slow only on Ubuntu.
I got a reply on the wxPython-users mailing list, the problem can be fixed by calling Layout explicitly before the dialog is shown.
This is really weird...
My guess is that this is due to
Windows and wxWidgets not dealing very
well with overlapping siblings, and so
when the sizer is doing the initial
layout and moving all the panels from
(0,0) to where they need to be that
something about the dialog is causing
all of them to be refreshed and
repainted at each move. If you
instead do the initial layout before
the dialog is shown then it is just as
fast as the frame.
You can do this by adding a call to window.Layout() at the end of
makegrid.
-- Robin Dunn

Categories