wxPython hide and show panel - python

I am creating a Python application that requires a login on start up. I want to have a main panel that will hold my login panel and on successful login the login panel will hide and the main wx.Notebook will show. The following code works, but if in the login panel I re-size the application, after I successfully login and go to the main wx.Notebook the wx.Notebook does not fit the size of the screen. If I resize again while in the main wx.Notebook the main wx.Notebook will fit the window. How do I get the main wx.Notebook to automatically re-size to the window?
Main.py
import wx
import os
from titlePanel import titlePanel
from OneLblOneCB_HorzBoxSizer_Panel import OneLblOneCB_HorzBoxSizer_Panel
from OneLblOneMultiTxt_HorzBoxSizer_Panel import OneLblOneMultiTxt_HorzBoxSizer_Panel
from OneLblOneSingleTxt_HorzBoxSizer_Panel import OneLblOneSingleTxt_HorzBoxSizer_Panel
from OneLblTxtFile_HorzBoxSizer_Panel import OneLblTxtFile_HorzBoxSizer_Panel
from OneBtn_HorzBoxSizer_Panel import OneBtn_HorzBoxSizer_Panel
from LoginPanel import LoginPanel
from ProjectsPanel import ProjectsPanel
from EvDB import EvDB
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title=title, size=(650,725))
# Create Database Tables
self.db = EvDB(self)
self.db.createTbls()
# Setting up the menu.
filemenu= wx.Menu()
ID_LOGIN = wx.NewId()
ID_LOGOUT = wx.NewId()
# wx.ID_ABOUT and wx.ID_EXIT are standard IDs provided by wxWidgets.
menuOpen = filemenu.Append(wx.ID_OPEN, "&Open"," Open and existing file")
menuAbout = filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
filemenu.AppendSeparator()
menuLogin = filemenu.Append(ID_LOGIN, 'Login')
menuLogout = filemenu.Append(ID_LOGOUT, 'Logout')
filemenu.AppendSeparator()
menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
# Creating the menubar.
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
# Set events.
self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen )
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout )
self.Bind(wx.EVT_MENU, self.OnLogin, menuLogin )
self.Bind(wx.EVT_MENU, self.OnLogout, menuLogout )
self.Bind(wx.EVT_MENU, self.OnExit, menuExit )
main = wx.Panel(self)
self.mainLogin = LoginPanel(main,-1,addSpacers=1)
self.mainLogin.Show()
# Create a notebook on the panel
self.nb = wx.Notebook(main)
self.nb.Hide()
# create the page windows as children of the notebook
flowchartPg = wx.Panel(self.nb)
entryPg = wx.ScrolledWindow(self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, style=wx.VSCROLL)
entryPg.SetScrollRate( 5, 5 )
projectsPg = ProjectsPanel(self.nb, -1)
# add the pages to the notebook with the label to show on the tab
self.nb.AddPage(projectsPg, "Projects")
self.nb.AddPage(entryPg, "Entry")
self.nb.AddPage(flowchartPg, "Flowchart")
self.entTitle = titlePanel(entryPg, -1)
self.entDescr = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
name="entDescr", lbl="Description")
self.srcTypeList = ['None','Website', 'Youtube', 'PDF', 'Book']
self.entSourceType = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
name="entSourceType", lbl="Source Type: ", cbList=self.srcTypeList, startVal='None')
self.entSource = OneLblTxtFile_HorzBoxSizer_Panel(entryPg,-1,
name="entSource", lbl="Source: ")
self.entSource.singleTxt.SetEditable(False)
self.entSource._filename.Disable()
self.entAuthor = OneLblOneSingleTxt_HorzBoxSizer_Panel(entryPg,-1,
name="entAuthor", lbl="Author: ", addSpacers=0)
self.entAuthorCre = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
name="entAuthorCre", lbl="Author's Credentials: ")
self.asPrjList = ['None','Project1', 'Project2', 'Project3', 'Project4']
self.entAsProject = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
name="asProject", lbl="Assign to Project: ", cbList=self.asPrjList, startVal='None')
self.saveOrEditList = ['New','Ev1', 'Ev2', 'Ev3', 'Ev4']
self.entSaveOrEdit = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
name="saveOrEdit", lbl="New or Edit: ", cbList=self.saveOrEditList, startVal='New')
self.entRemarks = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
name="sourceRemarks", lbl="Evidence Remarks: ")
self.entRemarks.multiTxt.SetEditable(False)
self.entAddBtn = OneBtn_HorzBoxSizer_Panel(entryPg, -1, name="entAddBtn", btn="Add")
self.entSaveBtn = OneBtn_HorzBoxSizer_Panel(entryPg, -1, name="entSaveBtn", btn="Save")
#self.loginTest = LoginPanel(entryPg, -1,addSpacers=1)
self.entSaveBtn.button.Hide()
# Bindings
self.Bind(wx.EVT_COMBOBOX, self.SourceTypeEvtComboBox, self.entSourceType.cb)
self.Bind(wx.EVT_COMBOBOX, self.AsProjectEvtComboBox, self.entAsProject.cb)
self.Bind(wx.EVT_COMBOBOX, self.SaveOrEditEvtComboBox, self.entSaveOrEdit.cb)
self.Bind(wx.EVT_BUTTON, self.EvtAddBtn, self.entAddBtn.button)
self.Bind(wx.EVT_BUTTON, self.EvtSaveBtn, self.entSaveBtn.button)
self.Bind(wx.EVT_BUTTON, self.EvtLoginBtn, self.mainLogin.loginBtns.LoginBtn)
self.Bind(wx.EVT_BUTTON, self.EvtLogoutBtn, self.mainLogin.loginBtns.LogoutBtn)
# Creating Sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
entryPgBox = wx.BoxSizer(wx.VERTICAL)
# Adding Panels to BoxSizer entry panel sizer
mainSizer.AddSpacer(10)
mainSizer.Add(self.nb, 1, wx.ALL|wx.EXPAND)
mainSizer.Add(self.mainLogin, 1, wx.ALL|wx.EXPAND)
entryPgBox.AddSpacer(20)
entryPgBox.Add(self.entAsProject, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entSaveOrEdit, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entTitle, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entDescr, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entSourceType, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entSource, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entAuthor, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entAuthorCre, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entRemarks, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
entryPgBox.Add(self.entAddBtn, 0, wx.EXPAND)
entryPgBox.Add(self.entSaveBtn, 0, wx.EXPAND)
entryPgBox.AddSpacer(10)
# Setting Layouts
entryPg.SetAutoLayout(True)
entryPg.SetSizer(entryPgBox)
entryPgBox.Fit(entryPg)
main.SetAutoLayout(True)
main.SetSizer(mainSizer)
mainSizer.Fit(main)
self.Layout()
self.Show()
def OnLogin(self,e):
self.nb.Hide()
self.mainLogin.Show()
self.Layout()
self.mainLogin.Layout()
def OnLogout(self,e):
self.mainLogin.Show()
self.nb.Hide()
self.Layout()
self.mainLogin.Layout()
def EvtLoginBtn(self,e):
self.nb.Show()
self.mainLogin.Hide()
self.Layout()
self.nb.Layout()
LoginPanel.py
class LoginPanel(wx.Panel):
def __init__(self, parent, ID, addSpacers):
wx.Panel.__init__(self, parent, ID)
sizer = wx.BoxSizer(wx.VERTICAL)
self.userNamePnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
name="loginUser", lbl="Username: ", addSpacers=1)
self.passwordPnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
name="loginPass", lbl="Password: ", addSpacers=1)
self.loginBtns = LoginBtnsPanel(self,-1)
if addSpacers == 1:
sizer.AddStretchSpacer()
sizer.Add(self.userNamePnl,0,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.passwordPnl,0,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.loginBtns,0,wx.EXPAND)
if addSpacers == 1:
sizer.AddStretchSpacer()
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)

Got it! I was trying to redraw the frame with Layout(), but I needed to redraw the BoxSizer with Layout()
I added the following code to the login button:
def EvtLoginBtn(self,e):
self.nb.Show()
self.mainLogin.Hide()
self.mainSizer.Layout()

Call the Layout() method of the Frame and Panel like this
def EvtLoginBtn(self,e):
self.nb.Show()
self.mainLogin.Hide()
self.Layout()
self.nb.Layout()
The last call is probably not needed. Just check the program without it as well. The Layout() method redraws the Frame or Panel or whichever widget it is a method of.
UPDATE
Your code is obviously very big and has several other parts which I do not know. Anyways, here's something that I came up with, along the lines of the code you have provided, to show how you can do this. Hope this helps:
Main.py
import wx
from LoginPanel import LoginPanel
class MyFrame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Something something", pos = wx.DefaultPosition, size = wx.Size( 300,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
BoxSizer0 = wx.BoxSizer( wx.VERTICAL )
# Add login panel
self.login_panel = LoginPanel(self)
BoxSizer0.Add(self.login_panel, 1, wx.EXPAND | wx.ALL, 0)
# Add notebook panel and its pages
self.nb = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
self.nb_subpanel1 = wx.Panel( self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
self.nb.AddPage( self.nb_subpanel1, u"something", False )
self.nb_subpanel2 = wx.Panel( self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
self.nb.AddPage( self.nb_subpanel2, u"something else", False )
BoxSizer0.Add( self.nb, 1, wx.EXPAND |wx.ALL, 0 )
# Adds a logout button
self.logout_button = wx.Button( self, wx.ID_ANY, u"Logout", wx.DefaultPosition, wx.DefaultSize, 0 )
BoxSizer0.Add( self.logout_button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
# Hide nb and logout button
self.nb.Hide()
self.logout_button.Hide()
self.SetSizer( BoxSizer0 )
self.Layout()
self.Centre( wx.BOTH )
self.Show()
# Connect Events
self.logout_button.Bind( wx.EVT_BUTTON, self.on_logout )
# Virtual event handlers, override them in your derived class
def on_logout( self, event ):
self.nb.Hide()
self.logout_button.Hide()
self.login_panel.Show()
self.Layout()
if __name__ == "__main__":
app = wx.App()
MyFrame(None)
app.MainLoop()
LoginPanel.py
import wx
class LoginPanel ( wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 300,300 ), style = wx.TAB_TRAVERSAL )
BoxSizer01 = wx.BoxSizer( wx.VERTICAL )
self.login_button = wx.Button( self, wx.ID_ANY, u"Login", wx.DefaultPosition, wx.DefaultSize, 0 )
self.login_button.SetDefault()
BoxSizer01.Add( self.login_button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
self.SetSizer( BoxSizer01 )
self.Layout()
# Connect Events
self.login_button.Bind( wx.EVT_BUTTON, self.on_login )
# Virtual event handlers, overide them in your derived class
def on_login( self, event ):
self.Hide()
self.Parent.nb.Show()
self.Parent.logout_button.Show()
self.Parent.Layout()

Related

How to plot more than once from same resource concurrency

I have 2 plotting buttons which takes the different datas from the same resource. Processing takes about 5 seconds. To be able press the second button in this time, I'm using wx.lib.delayedresult.
Before wx.lib.delayedresult, Pressing first button ---> processing takes 5s (during this time, i couldn't press second button) ---> RESULT 1. ---> pressing second button ---> 5s processing ---> RESULT 2. So ALL takes 10-11 seconds.
After wx.lib.delayedresult, pressing first button ---> processing takes 5s (during this time, pressing second button) ---> RESULT 1 ---> 5s ---> RESULT 2. So ALL takes 10-11 seconds.
What i want is, press first button ---> 5s processing(also press second button in this time) ---> RESULT 1 and RESULT 2. ALL should take 5-6 seconds.
Is this possible only with wx.lib.delayedresult? Or should i use thread, queue, processing etc?
Any suggestion would be greatly appreciated.
This is an small example of wx.lib.delayedresult.
from time import sleep
import wx
from wx.lib.delayedresult import startWorker
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = wx.Panel(self)
self.startButton = wx.Button(self.panel, label="Long Task")
self.Button1 = wx.Button(self.panel, label="btn1")
self.Button2 = wx.Button(self.panel, label="btn2")
self.startButton.Bind(wx.EVT_BUTTON, self.OnStartButton)
self.Button1.Bind(wx.EVT_BUTTON, self.OnBtn)
self.Button2.Bind(wx.EVT_BUTTON, self.heyBtn)
self.windowSizer = wx.BoxSizer()
self.windowSizer.Add(self.panel, 1, wx.ALL | wx.EXPAND)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.startButton)
self.sizer.Add(self.Button1)
self.sizer.Add(self.Button2)
self.sizer.Add((10, 10))
self.border = wx.BoxSizer()
self.border.Add(self.sizer, 1, wx.ALL | wx.EXPAND, 5)
self.panel.SetSizerAndFit(self.border)
self.SetSizerAndFit(self.windowSizer)
self.Show()
def OnStartButton(self, e):
self.startButton.Disable()
startWorker(self.LongTaskDone, self.LongTask)
def OnBtn(self, e):
hey(self).Show()
def heyBtn(self, event):
self.Button2.Disable()
startWorker(self.LongTaskDone_2, self.LongTask)
def LongTask_2(self):
print("LT 2")
sleep(5)
def LongTaskDone_2(self, result):
self.Button2.Enable()
print("ended 2")
def LongTask(self):
print("LT 1")
sleep(5)
print("hello")
def LongTaskDone(self, result):
print("ended 1")
self.startButton.Enable()
class hey(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
Below, LongTask btn takes processing 5s, btn1 takes it 5s seperately. ALL together gives the result in 8-9seconds. How can i get all results in 5 seconds?
from time import sleep
import wx
import wx.lib.agw.aui as aui
from wx.lib.delayedresult import startWorker
import serial
import matplotlib.pyplot as plt
from matplotlib.pyplot import subplot
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
import threading
class MainWindow(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__ ( self, parent )
self.panel = wx.Panel(self)
self.startButton = wx.Button(self.panel, label="Long Task")
self.Button1 = wx.Button(self.panel, label="btn1")
self.startButton.Bind(wx.EVT_BUTTON, self.OnStartButton)
self.Button1.Bind(wx.EVT_BUTTON, self.OnBtn)
self.windowSizer = wx.BoxSizer()
self.windowSizer.Add(self.panel, 1, wx.ALL|wx.EXPAND )
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.startButton)
self.sizer.Add(self.Button1)
self.sizer.Add((10, 10))
self.border = wx.BoxSizer()
self.border.Add(self.sizer, 1, wx.ALL|wx.EXPAND , 5)
#in attached file
self.x=[50144.0.... #[1]
self.y=[11.0, ... #[1]
self.z=[111.3, ... #[1]
self.panel.SetSizerAndFit(self.border)
self.SetSizerAndFit(self.windowSizer)
self.panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
self.panel2.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_ACTIVECAPTION ) )
self.border.Add(self.panel2, 1, wx.ALL | wx.EXPAND, 5)
############################################ AUI windows
self._mgr = aui.AuiManager()
self._mgr.SetManagedWindow(self)
self._mgr.AddPane(self.panel, aui.AuiPaneInfo().Name("tb1").Caption("Toolbar").ToolbarPane().Right())
self._mgr.AddPane(self.panel2, aui.AuiPaneInfo().CenterPane().Caption("Sabit"))
self._mgr.SetDockSizeConstraint(0.3, 0.65) #(w,h)
self._mgr.Update()
############################################
def OnStartButton(self, e):
self.startButton.Disable()
##################################### aui-canvas
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.panel5 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer14 = wx.BoxSizer( wx.VERTICAL )
self.figure2 = Figure((5,4), 85)
self.axes2 = self.figure2.add_subplot(111)
self.canvas2 = FigureCanvas(self.panel5, -1, self.figure2)
self.toolbar2 = NavigationToolbar(self.canvas2)
self.toolbar2.Realize()
bSizer14.Add(self.canvas2, 0, wx.ALL, 5 )
bSizer14.Add(self.toolbar2, 0, wx.ALL, 5 )
self.panel5.SetSizer( bSizer14 )
self.panel5.Layout()
bSizer14.Fit( self.panel5 )
bSizer1.Add( self.panel5, 1, wx.ALL, 5 )
self._mgr.AddPane(self.panel5, aui.AuiPaneInfo().Bottom().Caption("Start"))
self._mgr.Update()
##################################### aui
startWorker(self.LongTaskDone, self.LongTask)
def OnBtn(self, e):
##################################### aui-canvas
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.panel50 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer14 = wx.BoxSizer( wx.VERTICAL )
self.figure20 = Figure((5,4), 85)
self.axes20 = self.figure20.add_subplot(111)
self.canvas20 = FigureCanvas(self.panel50, -1, self.figure20)
bSizer14.Add(self.canvas20, 0, wx.ALL, 5 )
self.panel50.SetSizer( bSizer14 )
self.panel50.Layout()
bSizer14.Fit( self.panel50 )
bSizer1.Add( self.panel50, 0, wx.ALL, 5 )
self._mgr.AddPane(self.panel50, aui.AuiPaneInfo().Bottom().Caption("Btn"))
self._mgr.Update()
##################################### aui-canvas
self.axes20.bar(self.x, self.z)
self.canvas20.draw()
def LongTask(self):
self.axes2.bar(self.x, self.y)
self.canvas2.draw()
def LongTaskDone(self, result):
print("ended 1")
self.startButton.Enable()
def thread():
thread1 = threading.Thread(target = OnStartButton)
thread2 = threading.Thread(target = OnBtn)
thread1.start()
thread2.start()
app = wx.App(False)
win = MainWindow(None)
win.Show(True)
app.MainLoop()
[1]: https://www.mediafire.com/file/yc2a52cyhvsu5hl/x-y-z.txt/file

Is it possible to adapt width wx.StaticBox?

i've made this code :
import wx
import List as li
from ChoiceBook import *
class MainTab(wx.Panel):
def __init__(self, parent, sb, dm):
wx.Panel.__init__(self, parent)
self.parent = parent
self.hardware = []
box = wx.StaticBox(self, wx.ID_ANY, "Appareil")
self.list = li.List(self, sb, dm)
sizerleft = wx.StaticBoxSizer(box,wx.HORIZONTAL)
sizerleft.Add(self.list, 1, wx.ALL|wx.EXPAND, 5)
box = wx.StaticBox(self, wx.ID_ANY, "Mesures")
self.notebook = Choicebook(self,dm)
sizerright = wx.StaticBoxSizer(box,wx.HORIZONTAL)
sizerright.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(sizerleft, 1, wx.ALL|wx.EXPAND, 5)
sizer.Add(sizerright, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def update(self):
self.notebook.update()
it made this window, but when i resize it, it dosen't scale the contents. it just crop it, like this.
I think the probleme come from the StaticBox which are static i guess(i'm not sure).
I would like to know if it's possible to make it resize automatically?
or if not is there is another way to make a box whith a title like StaticBox and so make it resizable ?
EDIT: i figure it out with your help. in fact this wasn't this portion of cod fault but my list Class. i just remove all size in that file
before
wx.ListCtrl.__init__(self,
parent,
size=(800, -1),
style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
self.rm = RM.Res_Man()
self.index = 0
self.InsertColumn(0, 'Appareil de mesure', width=125)
self.InsertColumn(1, 'Connecté')
self.InsertColumn(2, 'ID',width=300)
self.InsertColumn(3, 'Type',width=290)
self.sb = sb
after
wx.ListCtrl.__init__(self,
parent,
style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
self.rm = RM.Res_Man()
self.index = 0
self.InsertColumn(0, 'Appareil de mesure')
self.InsertColumn(1, 'Connecté')
self.InsertColumn(2, 'ID')
self.InsertColumn(3, 'Type')
self.sb = sb
thanks you all ;)
I think that what you want, is to force it to Layout() on a RESIZE event.
However, remember that these items will have a minimum size.
Try this:
import wx
class MainTab(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
self.hardware = []
box = wx.StaticBox(self, wx.ID_ANY, "Appareil")
lc = wx.ListCtrl(self, wx.ID_ANY, style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
lc.InsertColumn(1, "Appareil de mesure")
lc.InsertColumn(2, "Connecte")
lc.InsertColumn(3, "ID")
lc.InsertColumn(4, "Type")
sizerleft = wx.StaticBoxSizer(box,wx.HORIZONTAL)
sizerleft.Add(lc, 1, wx.ALL|wx.EXPAND, 5)
box = wx.StaticBox(self, wx.ID_ANY, "Mesures")
cb = wx.Choicebook(self, wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name="")
sizerright = wx.StaticBoxSizer(box,wx.HORIZONTAL)
sizerright.Add(cb, 1, wx.ALL|wx.EXPAND, 5)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(sizerleft, 1, wx.ALL|wx.EXPAND, 5)
sizer.Add(sizerright, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
self.Bind(wx.EVT_SIZE, self.ReSize)
def ReSize(self,event):
self.Layout()
if __name__ == '__main__':
app = wx.App()
frame = MainTab()
frame.Show(True)
app.MainLoop()
I have had to hack it together as your code is in complete.

wxpython assign variable in an event handler

I would like to assign the value of a menu click to a class variable so I can use that value throughout multiple classes. Any help would be greatly appreciated!
import wx
class TrackPanel (wx.Panel):
""""""
def __init__(self, parent, *args, **kwargs):
"""Constructor"""
wx.Panel.__init__(self, parent, *args, **kwargs)
mainSizer =wx.BoxSizer(wx.VERTICAL)
track = MasterPage.track_selected # This is where i would like access the variable
title = wx.StaticText(self, wx.ID_ANY, label = track)
mainSizer.Add(title, 0,wx.ALL | wx.EXPAND | wx.CENTER)
self.SetSizerAndFit(mainSizer)
self.Layout()
class MasterPage (wx.Frame):
track_selected = ' '
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
menubar = wx.MenuBar()
tracksopt = wx.Menu()
track_command = wx.MenuItem(tracksopt, wx.ID_ANY, 'Atlanta')
tracksopt.Append(track_command)
self.Bind(wx.EVT_MENU, self.change_track, track_command)
track_command2 = wx.MenuItem(tracksopt, wx.ID_ANY, 'Texas')
tracksopt.Append(track_command2)
self.Bind(wx.EVT_MENU, self.change_track, track_command2)
menubar.Append(tracksopt, '&Tracks')
self.SetMenuBar(menubar)
def change_track (self, event):
"""Changes the tack_selected variable based on the menu item picked"""
id_selected = event.GetId()
obj = event.GetEventObject()
track_id= obj.GetLabel(id_selected)
MasterPage.track_selected = track_id
You must create a link to the master in the tracker in order for the tracker to access values in the master.
import wx
class Track (wx.Frame):
def __init__(self, link):
wx.Frame.__init__(self, None)
self.link = link
self.tc = wx.TextCtrl(self, style=wx.TE_MULTILINE)
self.bt = wx.Button(self, label="tracker (push to read master)")
self.bt.Bind(wx.EVT_BUTTON, self.on_read_master)
self.Title = 'Tracker'
sz_1 = wx.BoxSizer(wx.HORIZONTAL)
sz_2 = wx.BoxSizer(wx.VERTICAL)
sz_2.Add(self.tc, 1, wx.EXPAND, 0)
sz_2.Add(self.bt, 0, wx.EXPAND, 0)
sz_1.Add(sz_2, 1, wx.EXPAND, 0)
self.SetSizer(sz_1)
self.Layout()
self.SetSize((250, 100))
def on_read_master(self, evt):
self.tc.SetValue(self.link.track_selected) # here you access the variable)
class Master(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
self.track_selected = '0'
self.tc = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE)
self.bt = wx.Button(self, wx.ID_ANY, "master (push to send)")
self.bt.Bind(wx.EVT_BUTTON, self.change_track)
self.Title = 'Master'
self.tc.SetValue('enter value to be read by the tracker')
sz_1 = wx.BoxSizer(wx.HORIZONTAL)
sz_2 = wx.BoxSizer(wx.VERTICAL)
sz_2.Add(self.tc, 1, wx.EXPAND, 0)
sz_2.Add(self.bt, 0, wx.EXPAND, 0)
sz_1.Add(sz_2, 1, wx.EXPAND, 0)
self.SetSizer(sz_1)
self.Layout()
self.SetSize((250, 100))
def change_track (self, evt):
"""Changes variable based on text entered"""
self.track_selected = self.tc.GetValue()
if __name__ == "__main__":
app = wx.App(0)
master = Master()
track = Track(master)
master.Show()
track.Show()
app.MainLoop()
This is the fast and dirty method I generally use. If you want something more sophisticated, there is a dedicated library to pass messages between frames: pubsub. A good tutorial of how to use it can be found in the Mike Driscoll blog

How to add and edit time in a textctrl in wxpython?

I am developing a GUI using wxpython where i need a textctrl which selects the time .I tried with TimePickerCtrl but failed to fetch the time into the textctrl. It would be great if anyone shares a good example code which adds a time to a textctrl and can be edit the textctrl at any time.Thanks in advance.
Did you even look at the wxPython demo? It shows 3 different ways to create the picker control:
import wx
import wx.lib.masked as masked
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
# 12-hour format
text1 = wx.StaticText( self, -1, "12-hour format:", size=(150,-1))
self.time12 = masked.TimeCtrl( self, -1, name="12 hour control" )
h = self.time12.GetSize().height
spin1 = wx.SpinButton(
self, -1, wx.DefaultPosition, (-1,h), wx.SP_VERTICAL )
self.time12.BindSpinButton( spin1 )
self.addWidgets([text1, self.time12, spin1])
# 24-hour format
text2 = wx.StaticText( self, -1, "24-hour format:")
spin2 = wx.SpinButton(
self, -1, wx.DefaultPosition, (-1,h), wx.SP_VERTICAL )
self.time24 = masked.TimeCtrl(
self, -1, name="24 hour control", fmt24hr=True,
spinButton = spin2
)
self.addWidgets([text2, self.time24, spin2])
# No seconds\nor spin button
text3 = wx.StaticText( self, -1, "No seconds\nor spin button:")
self.spinless_ctrl = masked.TimeCtrl(
self, -1, name="spinless control",
display_seconds = False
)
self.addWidgets([text3, self.spinless_ctrl])
# set sizer
self.SetSizer(self.mainSizer)
def addWidgets(self, widgets):
sizer = wx.BoxSizer(wx.HORIZONTAL)
for widget in widgets:
if isinstance(widget, wx.StaticText):
sizer.Add(widget, 0, wx.ALL|wx.CENTER, 5),
else:
sizer.Add(widget, 0, wx.ALL, 5)
self.mainSizer.Add(sizer)
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Spinner Demo")
panel = MyPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
f = MyFrame()
app.MainLoop()

wxPython: Problems with GridBagSizer

I'm new to wxpython and it seems to be very powerful tool for building up GUI, but I have a question about GridBagSizer. Could you please tell me how to adjust the size of the items that are placed inside GridBagSizer to the size of the frame they are supposed to be placed in. I attached the sample at the end: the buttons from 8 to 13 go beyond the frame, but what I want is to make the size of the buttons automatically resize to fit the frame. Any advices and suggestions are appreciated.
Best regards,
Nikita
import wx
class Frame ( wx.Frame ):
def __init__( self ):
wx.Frame.__init__ ( self, None, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE & ~ (wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX|wx.RESIZE_BORDER) )
nums = (('1',(0,3)), ('2',(2,3)), ('14', (3,3)), ('15',(4,3)), ('16',(5,3)), ('17',(6,3)), ('18',(7,3)),
('3',(1,0)), ('4',(1,1)), ('5',(1,2)), ('6',(1,3)), ('7',(1,4)), ('8',(1,5)), ('9',(1,6)), ('10',(1,7)),
('11',(1,8)), ('12',(1,9)), ('13',(1,10)))
panel = wx.Panel(self,-1)
panel.SetBackgroundColour("green")
grid = wx.GridBagSizer(2,2)
for num, pos in nums:
button = wx.Button(panel, wx.NewId(), label = num)
grid.Add(button, pos, flag=wx.EXPAND)
bs2 = wx.BoxSizer(wx.VERTICAL)
bs2.Add(grid, 0, wx.EXPAND,0)
panel.SetSizer(bs2)
panel.Layout()
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.mainSizer.Add(panel, 0, wx.EXPAND, 0)
self.SetSizer(self.mainSizer)
self.Layout()
if __name__=='__main__':
app=wx.PySimpleApp()
app.frame = Frame()
app.frame.Center()
app.frame.Show(True)
app.MainLoop()
You must allow the columns to grow by calling AddGrowableCol:
for i in range(11):
grid.AddGrowableCol(i)
Now, they can grow, but they won't shrink beyond their initial size! So you should also reduce their starting size:
for num, pos in nums:
button = wx.Button(panel, wx.NewId(), size=(10,-1), label = num)
#original code was: button = wx.Button(panel, wx.NewId(), label = num)
grid.Add(button, pos, flag=wx.EXPAND)
Here is the complete listing:
import wx
class Frame ( wx.Frame ):
def __init__( self ):
wx.Frame.__init__ ( self, None, id = wx.ID_ANY, title = wx.EmptyString, pos =
wx.DefaultPosition, size = wx.Size( 500,300 ),
style = wx.DEFAULT_FRAME_STYLE & ~ (wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX|wx.RESIZE_BORDER) )
nums = (('1',(0,3)), ('2',(2,3)), ('14', (3,3)), ('15',(4,3)), ('16',(5,3)), ('17',(6,3)), ('18',(7,3)),
('3',(1,0)), ('4',(1,1)), ('5',(1,2)), ('6',(1,3)), ('7',(1,4)), ('8',(1,5)), ('9',(1,6)), ('10',(1,7)),
('11',(1,8)), ('12',(1,9)), ('13',(1,10)))
panel = wx.Panel(self,-1)
panel.SetBackgroundColour("green")
grid = wx.GridBagSizer(2,2)
for num, pos in nums:
button = wx.Button(panel, wx.NewId(), size=(10,-1), label = num)
grid.Add(button, pos, flag=wx.EXPAND)
for i in range(11):
grid.AddGrowableCol(i)
bs2 = wx.BoxSizer(wx.VERTICAL)
bs2.Add(grid, 0, wx.EXPAND,0)
panel.SetSizer(bs2)
panel.Layout()
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.mainSizer.Add(panel, 0, wx.EXPAND, 0)
self.SetSizer(self.mainSizer)
self.Layout()
if __name__=='__main__':
app=wx.PySimpleApp()
app.frame = Frame()
app.frame.Center()
app.frame.Show(True)
app.MainLoop()

Categories