We all know that the wxPython toolbar is most of the time, if not always placed at the top. But is there a way to have it on the side (left preferably)? Is there a way to turn this code's (taken from here) top toolbar into a side toolbar:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
This example creates a simple toolbar.
author: Jan Bodnar
website: www.zetcode.com
last modified: April 2018
"""
import wx
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
toolbar = self.CreateToolBar()
qtool = toolbar.AddTool(wx.ID_ANY, 'Quit', wx.Bitmap('texit.png'))
toolbar.Realize()
self.Bind(wx.EVT_TOOL, self.OnQuit, qtool)
self.SetSize((350, 250))
self.SetTitle('Simple toolbar')
self.Centre()
def OnQuit(self, e):
self.Close()
def main():
app = wx.App()
ex = Example(None)
ex.Show()
app.MainLoop()
if __name__ == '__main__':
main()
Make use of the toolbar Style attributes.
import wx
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
toolbar = self.CreateToolBar(wx.TB_VERTICAL|wx.TB_TEXT)
atool = toolbar.AddTool(wx.ID_ANY, 'Tool_A', wx.Bitmap('stop.png'))
btool = toolbar.AddTool(wx.ID_ANY, 'Tool_B', wx.Bitmap('stop.png'))
ctool = toolbar.AddTool(wx.ID_ANY, 'Quit', wx.Bitmap('stop.png'))
toolbar.Realize()
self.Bind(wx.EVT_TOOL, self.OnQuit, ctool)
self.SetSize((350, 250))
self.SetTitle('Simple toolbar')
self.Centre()
def OnQuit(self, e):
self.Close()
def main():
app = wx.App()
ex = Example(None)
ex.Show()
app.MainLoop()
if __name__ == '__main__':
main()
Styles available:
wx.TB_FLAT: Gives the toolbar a flat look (Windows and GTK only).
wx.TB_DOCKABLE: Makes the toolbar floatable and dockable (GTK only).
wx.TB_HORIZONTAL: Specifies horizontal layout (default).
wx.TB_VERTICAL: Specifies vertical layout.
wx.TB_TEXT: Shows the text in the toolbar buttons; by default only icons are shown.
wx.TB_NOICONS: Specifies no icons in the toolbar buttons; by default they are shown.
wx.TB_NODIVIDER: Specifies no divider (border) above the toolbar (Windows only)
wx.TB_NOALIGN: Specifies no alignment with the parent window (Windows only, not very useful).
wx.TB_HORZ_LAYOUT: Shows the text and the icons alongside, not vertically stacked (Windows and GTK 2 only). This style must be used with TB_TEXT .
wx.TB_HORZ_TEXT: Combination of TB_HORZ_LAYOUT and TB_TEXT .
wx.TB_NO_TOOLTIPS: Don’t show the short help tooltips for the tools when the mouse hovers over them.
wx.TB_BOTTOM: Align the toolbar at the bottom of parent window.
wx.TB_RIGHT: Align the toolbar at the right side of parent window.
wx.TB_DEFAULT_STYLE: Combination of TB_HORIZONTAL and TB_FLAT . This style is new since wxWidgets 2.9.5.
Related
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()
I've tried to put a MenuBar but it doesn't appear, and I don't know what I doing wrong.
from PyQt4 import QtGui
import sys
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setWindowTitle("IDE")
self.initUI
def initUI(self):
grid = QtGui.QGridLayout(self)
menuBar = QtGui.QMenuBar(self)
self.fileMenu = menuBar.addMenu("File")
grid.addWidget(menuBar, 0, 0)
self.setLayout(grid)
and the result:
You'll need to set the menubar on the main window
self.setMenuBar(menuBar)
In many cases, you don't need to create the menubar manually, you can just call .menuBar() on the main window and it will return the current one or create one if it doesn't exist. This is the preferred way if there's a chance your .ui file contains a menubar and menubar items.
menubar = self.menuBar()
Also, you can't add QMenuBars to layouts - from the docs:
There is no need to lay out a menu bar. It automatically sets its own geometry to the top of the parent widget and changes it appropriately whenever the parent is resized.
I am using PyQt to create a desktop application. I am trying to create a button using hbox and vbox, but it doesn't display unless I give the specific command:
button1 = QtGui.QPushButton("Exit", self)
But, by doing this, the vbox and hbox functionality doesn't seem to function.
I need the button to be on the bottom-right corner of the window, which stays there even after window-resize.
With this code, it is positioned on the top-left corner.
from PyQt4 import QtGui, QtCore
import sys
class Trial(QtGui.QMainWindow):
def __init__(self):
super(Trial,self).__init__()
self.createUI()
def createUI(self):
button1 = QtGui.QPushButton("Exit",self)
button1.clicked.connect(self.close)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1) #stretches it to the right end of the page
hbox.addWidget(button1)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1) #stretches it to the bottom end of the page
vbox.addLayout(hbox)
self.setLayout(vbox)
button1.resize(button1.sizeHint())
self.setGeometry(300,200,750,450)
self.setWindowTitle('Testing')
self.show()
def main():
app= QtGui.QApplication(sys.argv)
w=Trial()
sys.exit(app.exec_())
if __name__=='__main__':
main()
If I use button1.move(420, 400), it moves the button to the position I want, but it doesn't stay there when I re-size the application window.
The example code doesn't work because you are trying to set a layout on the main window, which already has a layout.
Instead, you need to add a central widget, and then set the layout on that:
def createUI(self):
self.setCentralWidget(QtGui.QWidget(self))
...
vbox.addLayout(hbox)
self.centralWidget().setLayout(vbox)
self.setGeometry(300,200,750,450)
...
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.
I'm trying to get my empty frame so that when I click the X it just hides the window, and then if I hit the dock icon it'll reveal the window. It's turning out to be more of a challenge than I expected.. I used http://wiki.wxpython.org/Optimizing%20for%20Mac%20OS%20X/ but I can't make ends of it.
Here's my code:
import wx
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "title",style=wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CAPTION, size=(300,300))
panel = wx.Panel(self)
def MacReopenApp(self, event):
print "Attempting to reveal the window."
def MacHideApp(self, event):
print "Attempting to hide the window."
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()
The document you link to states that you need to add those event handlers on the App. You have currently defined them on a frame. So you need to extend wx.App and define those event handlers, and instantiate your own App instead of wx.App.
So (shortened example copied from your link):
class MyApp(wx.App):
def __init__(self, *args, **kwargs):
wx.App.__init__(self, *args, **kwargs)
# This catches events when the app is asked to activate by some other
# process
self.Bind(wx.EVT_ACTIVATE_APP, self.OnActivate)
#.....
def MacReopenApp(self):
"""Called when the doc icon is clicked, and ???"""
self.BringWindowToFront()
app = MyApp(False)
app.MainLoop()