Updating Static label in wxpython on event trigger - python

I am building an application that will show basic info about a motorcycle such as RPM and the gear it is in. Say we change gear with a "keyboard button press", how could I get it to update the label. Suppose the equivalent key would be the UP key to go up, so far this is what I came up with but the label wont update when the event is being triggered. What may I be doing wrong?
import wx
import sys
var =int(sys.argv[1])
gr = "N"
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.gauge_1 = wx.Gauge(self, wx.ID_ANY, 10000, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH)
self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle("Test")
self.gauge_1.SetBackgroundColour(wx.Colour(216, 216, 191))
self.gauge_1.SetForegroundColour(wx.Colour(128, 0, 206))
self.gauge_1.SetFont(wx.Font(11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, "Ubuntu"))
self.gauge_1.SetValue(var)
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.gauge_1, 0, wx.EXPAND, 0)
label_1 = wx.StaticText(self, wx.ID_ANY, "GEAR")
label_1.SetMinSize((100, 50))
label_1.SetForegroundColour(wx.Colour(0, 137, 215))
label_1.SetFont(wx.Font(25, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL, 0, ""))
sizer_1.Add(label_1, 0, wx.ALL, 3)
Gearind = wx.StaticText(self, wx.ID_ANY, gr, style=wx.ALIGN_CENTER)
Gearind.SetMinSize((50, 43))
Gearind.SetForegroundColour(wx.Colour(122, 0, 7))
Gearind.SetFont(wx.Font(32, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_SLANT, wx.FONTWEIGHT_NORMAL, 0, ""))
sizer_1.Add(Gearind, 0, 0, 0)
self.SetSizer(sizer_1)
self.Layout()
def OnKeyUp(self, evt):
code = evt.GetKeyCode()
if code == wx.WXK_UP:
gr = "1"
self.Gearind.SetLabel(gr)
elif code == wx.WXK_DOWN:
evt.Skip()
class MyApp(wx.App):
def OnInit(self):
self.Test = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.Test)
self.Test.Show()
return True
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()

I don't believe a Frame accepts characters.
Use a wx.Window with style wx.WANTS_CHARS or a wx.Panel
It won't help that you want to update self.Gearind but you defined it as a local i.e. Gearind.
Below, I've added a panel and a few other tweaks (note the gauge value).
You might want to investigate the wxpython SpeedMeter which may add some Vroooom! to your program.
import wx
import sys
try:
var =int(sys.argv[1])
except Exception:
var = 0
gr = "N"
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, wx.ID_ANY)
self.SetSize((400, 300))
self.panel = wx.Panel(self, wx.ID_ANY)
self.gauge_1 = wx.Gauge(self.panel, wx.ID_ANY, 6, style=wx.GA_HORIZONTAL | wx.GA_SMOOTH)
self.panel.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle("Test")
#self.gauge_1.SetBackgroundColour(wx.Colour(216, 216, 191))
#self.gauge_1.SetForegroundColour(wx.Colour(128, 0, 206))
#self.gauge_1.SetFont(wx.Font(11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, "Ubuntu"))
self.gauge_1.SetValue(var)
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.gauge_1, 0, wx.EXPAND, 0)
label_1 = wx.StaticText(self.panel, wx.ID_ANY, "GEAR")
label_1.SetMinSize((100, 50))
label_1.SetForegroundColour(wx.Colour(0, 137, 215))
label_1.SetFont(wx.Font(25, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL, 0, ""))
sizer_1.Add(label_1, 0, wx.ALL, 3)
self.Gearind = wx.StaticText(self.panel, wx.ID_ANY, gr, style=wx.ALIGN_CENTER)
self.Gearind.SetMinSize((50, 43))
self.Gearind.SetForegroundColour(wx.Colour(122, 0, 7))
self.Gearind.SetFont(wx.Font(32, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_SLANT, wx.FONTWEIGHT_NORMAL, 0, ""))
sizer_1.Add(self.Gearind, 0, 0, 0)
self.panel.SetSizer(sizer_1)
self.Layout()
def OnKeyUp(self, evt):
code = evt.GetKeyCode()
gr = self.Gearind.GetLabel()
if gr.isnumeric():
gr_up = int(gr) + 1
gr_down = int(gr) - 1
else:
gr_up = 1
gr_down = 0
if gr_up > 6:
gr_up = 6
if gr_down < 1:
gr_down = "N"
if code == wx.WXK_UP:
self.Gearind.SetLabel(str(gr_up))
elif code == wx.WXK_DOWN:
self.Gearind.SetLabel(str(gr_down))
gr = self.Gearind.GetLabel()
if gr == "N":
var = 0
else:
var = int(gr)
self.gauge_1.SetValue(var)
evt.Skip()
class MyApp(wx.App):
def OnInit(self):
self.Test = MyFrame(None)
self.SetTopWindow(self.Test)
self.Test.Show()
return True
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()

Related

Show matplotlib plot in a wxpython panel and update on button push

I am trying to plot 1D txt files in a part of the window created using wxpython. For this purpose, a directory selection tool was included which lists all txt files. Now, I would like to select a txt file and plot it in a panel on the right side.
Further, I am thinking to implement a button that does some operations on the data and replot again.
What I have tried is this :
import os
import wx
import numpy as np
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class mainFrame (wx.Frame):
def __init__(self):
super().__init__(None, id=wx.ID_ANY, title=u" test ",
size=wx.Size(854, 698),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetSizeHints(wx.Size(600, -1), wx.DefaultSize)
sizer = wx.BoxSizer(wx.VERTICAL)
self.panel = MainPanel(self, style=wx.TAB_TRAVERSAL)
self.Layout()
sizer.Add(self.panel, 1, wx.EXPAND, 0)
self.SetSizer(sizer)
self.Layout()
self.Centre()
# Connect Events
self.panel.dirPicker.Bind(wx.EVT_DIRPICKER_CHANGED, self.dirPickerOnDirChanged)
self.panel.listBox.Bind(wx.EVT_LISTBOX, self.listBoxOnListBox)
# ------------ Add widget program settings
# ------------ Call Populates
self.Show()
# Virtual event handlers, override them in your derived class
def dirPickerOnDirChanged(self, event):
self.FilePath = event.GetPath()
self.populateFileList()
def populateFileList(self):
self.panel.listBox.Clear()
allFiles = os.listdir(self.FilePath)
for file in allFiles:
if file.endswith('.txt'):
self.panel.listBox.Append(file)
def listBoxOnListBox(self, event):
try:
selected_file = event.GetString()
file_address = os.path.join(self.FilePath, selected_file)
# load file
data = np.loadtxt(file_address)
# select the first column
if isinstance(data, np.ndarray):
print("\tdata is np.array")
dim = data.ndim
if dim == 2:
input1D = data[:, 0]
else:
input1D = data
print(input1D.shape)
# plot here
else:
print("\tdata is not np.array")
except: # Do not use bare except
print("Some error.")
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.FONT_11 = wx.Font(11, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL, False, "Consolas")
self.FONT_12 = wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL, False, wx.EmptyString)
self.FONT_13 = wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL, False, wx.EmptyString)
self.FONT_14 = wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD, False, "Consolas")
self.FONT_16 = wx.Font(16, wx.FONTFAMILY_SCRIPT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD, False, wx.EmptyString)
sizer = wx.BoxSizer(wx.VERTICAL)
quick_display = self._quick_display()
directory_sizer = self._directory_sizer()
list_box_sizer = self._list_box_sizer()
self.text_details = self._detail_input()
details_sizer = self._details_sizer()
status_sizer = self._status_sizer()
message_sizer = wx.BoxSizer(wx.VERTICAL)
message_sizer.Add(details_sizer, 1, wx.EXPAND, 5)
message_sizer.Add(status_sizer, 1, wx.EXPAND, 5)
sizer.Add(quick_display, 0, wx.EXPAND, 0)
sizer.Add(directory_sizer, 0, wx.EXPAND, 0)
sizer.Add(list_box_sizer, 1, wx.EXPAND, 0)
sizer.Add(message_sizer, 1, wx.EXPAND, 5)
self.SetSizer(sizer)
def _quick_display(self):
quick_display = wx.StaticText(self, label=u"quick display")
quick_display.Wrap(-1)
quick_display.SetFont(self.FONT_16)
return quick_display
def _directory_sizer(self):
sbSizerDir = wx.StaticBoxSizer(wx.StaticBox(self, label=u" working directory"))
self.dirPicker = wx.DirPickerCtrl(sbSizerDir.GetStaticBox(), message=u"Select a folder")
sbSizerDir.Add(self.dirPicker, 0, wx.ALL | wx.EXPAND, 5)
return sbSizerDir
def _list_box(self):
listBoxChoices = []
self.listBox = wx.ListBox(self, size=wx.Size(300, -1), choices=listBoxChoices)
self.listBox.SetMinSize(wx.Size(250, -1))
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.listBox, 1, wx.ALL, 10)
return sizer
def _plot_sizer(self):
self.panelPlot = PlotPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panelPlot, 1, wx.EXPAND | wx.ALL, 5)
return sizer
def _list_box_sizer(self):
file_list_sizer = self._list_box()
bSizer_plot = self._plot_sizer()
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(file_list_sizer, 1, wx.EXPAND, 0)
sizer.Add(bSizer_plot, 1, wx.EXPAND, 5)
bSizerSplitHor = wx.BoxSizer(wx.HORIZONTAL)
bSizerSplitHor.Add(sizer, 1, wx.EXPAND, 2)
bSizerSplit = wx.BoxSizer(wx.VERTICAL)
bSizerSplit.Add(bSizerSplitHor, 1, wx.EXPAND, 0)
return bSizerSplit
def _detail_label(self):
detail_label = wx.StaticText(self, label="Details")
detail_label.Wrap(-1)
detail_label.SetFont(self.FONT_14)
return detail_label
def _detail_input(self):
text_details = wx.TextCtrl(self, size=wx.Size(250, -1))
text_details.SetFont(self.FONT_11)
return text_details
def _button_sizer(self):
self.button = wx.Button(self, label=u"do some operation")
self.button.SetFont(self.FONT_13)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.button, 0, wx.ALL, 5)
return sizer
def _details_sizer(self):
detail_label = self._detail_label()
button_sizer = self._button_sizer()
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(detail_label, 0, wx.ALL, 5)
sizer.Add(self.text_details, 1, wx.EXPAND, 5)
sizer.Add(button_sizer, 1, wx.EXPAND, 5)
return sizer
def _status_sizer(self):
self.staticline3 = wx.StaticLine(self)
self.status_label = wx.StaticText(self, label=u"Status bar")
self.status_label.Wrap(-1)
self.status_label.SetFont(self.FONT_12)
self.staticline4 = wx.StaticLine(self)
self.textCtrl_status = wx.TextCtrl(self)
self.textCtrl_status.SetFont(self.FONT_11)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.staticline3, 0, wx.EXPAND | wx.ALL, 5)
sizer.Add(self.status_label, 0, wx.ALL, 5)
sizer.Add(self.staticline4, 0, wx.EXPAND | wx.ALL, 5)
sizer.Add(self.textCtrl_status, 0, wx.ALL | wx.EXPAND, 5)
status_sizer = wx.BoxSizer(wx.VERTICAL)
status_sizer.Add(sizer, 1, wx.EXPAND, 5)
return status_sizer
class PlotPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.SetMinSize(wx.Size(100, -1))
if __name__ == "__main__":
app = wx.App(False)
frame = mainFrame()
app.MainLoop()
This creates a window as follows :
The right portion is assigned as a panel, and I not sure how to place the matplotlib plot in it. Thank you.
There are several good questions on SE probing this topic, such as Q1 and Q2; however, most are limited to the plot being shown on the main window.
wxGlade includes some wxPython / matplotlib examples. Use these as starting point.
https://github.com/wxGlade/wxGlade/tree/master/examples

Wxpython How to get the ComboBox's value of Panel1 from Panel2

Now I have two Panel Panelone and Paneltwo and use notebook in a Frame
and When I click the button, I want to return the value of Panelone to PanelTwo
like
class PanelTwo(wx.panel):
def __init__(self,parent):
super(PanelTwo,self).__init__(parent)
self.choice1 = wx.ComboBox(self,value=**the Panelone Value**,choices=,style=wx.CB_SORT, pos=(100, 5)) or
self.choice1.SetValue(the Panelone Value)
class Panelone(wx.panel):
def __init__(self,parent):
choicelist = ['1','2','3','5','6']
super(Panelone,self).__init__(parent)
self.choice = wx.ComboBox(self,value="1",choices=choicelist,style=wx.CB_SORT, pos=(100, 5))
self.btn = wx.Button(self, label="Summit",pos=(250, 10), size=(80, 50))
self.Bind(wx.EVT_BUTTON, self.BtnCheck, self.btn)
def BtnCheck(self,event):
**When I click the button, I want to return the value of Panelone to PanelTwo**
class Game(wx.Frame):
def __init__(self, parent, title):
super(Game, self).__init__(parent, title=title, size=(900, 700))
self.InitUI()
def InitUI(self):
nb = wx.Notebook(self)
nb.AddPage(PanelOne(nb), "PanelOne")
nb.AddPage(PanelTwo(nb), "PanelTwo")
self.Centre()
self.Show(True)
First of all, if you are learning, I recommend that you use WxGlade to build your graphical interfaces. Your code is pure spaghetti and is full of syntactic errors :(.
In the case of your example, it is very simple since all the elements belong to the same file and are in the same class.
For example:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import wx
# THE MAIN FRAME:
class MainFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((734, 501))
# The main notebook:
self.main_notebook = wx.Notebook(self, wx.ID_ANY)
# Notebook's panels:
self.panel1 = wx.Panel(self.main_notebook, wx.ID_ANY)
self.panel2 = wx.Panel(self.main_notebook, wx.ID_ANY)
# Content of panel1:
self.choiceFruits = wx.Choice(self.panel1, wx.ID_ANY, choices=[])
self.btn_send = wx.Button(self.panel1, wx.ID_ANY, "Send Value to Panel2")
#Content of panel2:
self.txt_result = wx.TextCtrl(self.panel2, wx.ID_ANY, "")
#Binding events:
# event, custom event handler, gui element
self.Bind(wx.EVT_BUTTON, self.OnBtnSendClick, self.btn_send)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle("frame")
choices = ['Apple', 'Banana', 'Peach', 'Strawberry']
self.choiceFruits.SetItems(choices)
self.choiceFruits.SetSelection(0)
def __do_layout(self):
# begin wxGlade: MainFrame.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
grid_sizer_1 = wx.FlexGridSizer(2, 2, 0, 10)
label_1 = wx.StaticText(self.panel1, wx.ID_ANY, "Choose a fruit:")
grid_sizer_1.Add(label_1, 0, wx.ALL, 10)
grid_sizer_1.Add((0, 0), 0, 0, 0)
grid_sizer_1.Add(self.choiceFruits, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
grid_sizer_1.Add(self.btn_send, 0, wx.BOTTOM | wx.EXPAND | wx.RIGHT, 10)
self.panel1.SetSizer(grid_sizer_1)
grid_sizer_1.AddGrowableCol(0)
label_2 = wx.StaticText(self.panel2, wx.ID_ANY, "You have selected:")
grid_sizer_2.Add(label_2, 0, wx.ALL, 10)
grid_sizer_2.Add(self.txt_result, 0, wx.ALL | wx.EXPAND, 10)
self.panel2.SetSizer(grid_sizer_2)
grid_sizer_2.AddGrowableCol(0)
self.main_notebook.AddPage(self.panel1, "Panel 1")
self.main_notebook.AddPage(self.panel2, "Panel 2")
sizer_1.Add(self.main_notebook, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
# end wxGlade
# Custom event handler:
def OnBtnSendClick(self, event):
selectedFruit = self.choiceFruits.GetString(self.choiceFruits.GetSelection())
self.txt_result.SetValue(selectedFruit)
wx.MessageBox("You have selected \"%s\"" % selectedFruit)
# The Main Class:
class MyApp(wx.App):
def OnInit(self):
self.main_frame = MainFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.main_frame)
self.main_frame.Show()
return True
# Main APP Method.
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
But this is not common. Usually each panel will be in a separate file within its own class. In that case, you must pass a reference from the main frame to each panel and then we use this reference to access the elements on the main frame (for example, another panel).
MAINFRAME
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import wx
from panel1 import Panel1
from panel2 import Panel2
# THE MAIN FRAME:
class MainFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((734, 501))
# The main notebook:
self.main_notebook = wx.Notebook(self, wx.ID_ANY)
# Notebook's panels:
self.panel1 = Panel1(self.main_notebook, wx.ID_ANY)
self.panel2 = Panel2(self.main_notebook, wx.ID_ANY)
# Pass reference of the main frame to each panel:
self.panel1.SetParent(self)
self.panel2.SetParent(self)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle("frame")
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
self.main_notebook.AddPage(self.panel1, "Panel 1")
self.main_notebook.AddPage(self.panel2, "Panel 2")
sizer_1.Add(self.main_notebook, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
# The Main Class:
class MyApp(wx.App):
def OnInit(self):
self.main_frame = MainFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.main_frame)
self.main_frame.Show()
return True
# Main APP Method.
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
PANEL 1
# -*- coding: UTF-8 -*-
import wx
class Panel1(wx.Panel):
def __init__(self, *args, **kwds):
# begin wxGlade: Panel1.__init__
kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
wx.Panel.__init__(self, *args, **kwds)
# Content of panel1:
self.choiceFruits = wx.Choice(self, wx.ID_ANY, choices=[])
self.btn_send = wx.Button(self, wx.ID_ANY, "Send Value to Panel2")
self._parent = None
#Binding events:
# event, custom event handler, gui element
self.Bind(wx.EVT_BUTTON, self.OnBtnSendClick, self.btn_send)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
choices = ['Apple', 'Banana', 'Peach', 'Strawberry']
self.choiceFruits.SetItems(choices)
self.choiceFruits.SetSelection(0)
def __do_layout(self):
grid_sizer_2 = wx.FlexGridSizer(2, 2, 0, 0)
label_2 = wx.StaticText(self, wx.ID_ANY, "Choose a fruit:")
grid_sizer_2.Add(label_2, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
grid_sizer_2.Add((0, 0), 0, 0, 0)
grid_sizer_2.Add(self.choiceFruits, 0, wx.ALL | wx.EXPAND, 10)
grid_sizer_2.Add(self.btn_send, 0, wx.BOTTOM | wx.RIGHT | wx.TOP, 10)
self.SetSizer(grid_sizer_2)
grid_sizer_2.Fit(self)
grid_sizer_2.AddGrowableCol(0)
self.Layout()
# end wxGlade
def SetParent(self, parent):
self._parent = parent
# Custom event handler:
def OnBtnSendClick(self, event):
selectedFruit = self.choiceFruits.GetString(self.choiceFruits.GetSelection())
# here is the trick !!!
self._parent.panel2.txt_result.SetValue(selectedFruit)
wx.MessageBox("You have selected \"%s\"" % selectedFruit)
PANEL 2
# -*- coding: UTF-8 -*-
import wx
class Panel2(wx.Panel):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
wx.Panel.__init__(self, *args, **kwds)
#Content of panel2:
self.txt_result = wx.TextCtrl(self, wx.ID_ANY, "")
self.__set_properties()
self.__do_layout()
def __set_properties(self):
pass
def __do_layout(self):
grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
label_2 = wx.StaticText(self, wx.ID_ANY, "You have selected:")
grid_sizer_2.Add(label_2, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
grid_sizer_2.Add(self.txt_result, 0, wx.ALL | wx.EXPAND, 10)
self.SetSizer(grid_sizer_2)
grid_sizer_2.Fit(self)
grid_sizer_2.AddGrowableCol(0)
self.Layout()
def SetParent(self, parent):
self._parent = parent
The trick is in the Panel1's (btn_send) button event handler:
# self._parent is a reference to MainFrame
# panel2 is a main_frame's element.
# txt_result is a TextCtrl in Panel2 class.
self._parent.panel2.txt_result.SetValue(selectedFruit)

Why does this StaticLine appear behind the sizer?

I'm trying to draw a static line between the "Label"+TextCtrl and the radio buttons.
It keeps appearing only when the window is dragged, and then it appears behind everything and I can't figure out why.
The goal is to have the static line draw horizontally between the upper and the lower section.
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame.__init__
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((237, 237))
self.__initUI()
self.__do_layout()
def __initUI(self):
panel = wx.Panel(self)
self.SetSize((350, 150))
self.qtyField = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_CENTER)
self.qtyField.SetFocus()
self.longRb = wx.RadioButton(panel, wx.ID_ANY, "This", style=wx.RB_GROUP)
self.shortRb = wx.RadioButton(panel, wx.ID_ANY, "That")
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
vertSizer = wx.BoxSizer(wx.VERTICAL)
horSizer1 = wx.GridSizer(1, 2, 0, 0)
rbSizer = wx.GridSizer(1, 2, 0, 36)
qtyLabel = wx.StaticText(self, wx.ID_ANY, "Label")
horSizer1.Add(qtyLabel, 0, wx.ALIGN_CENTER, 0)
horSizer1.Add(self.qtyField, 0, wx.ALIGN_CENTER_VERTICAL, 0)
vertSizer.Add(horSizer1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 6)
static_line_1 = wx.StaticLine(self, wx.ID_ANY)
vertSizer.Add(static_line_1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 6)
rbSizer.Add(self.longRb, 0, wx.ALIGN_CENTER, 0)
rbSizer.Add(self.shortRb, 0, wx.ALIGN_CENTER, 0)
vertSizer.Add(rbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 6)
self.SetSizer(vertSizer)
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
# end of class MyApp
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
Your are assigning some widgets to the Frame (self) and others to the panel, so they present themselves where instructed to do so.
This is what you are after:
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame.__init__
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((237, 237))
self.__initUI()
self.__do_layout()
def __initUI(self):
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour("green")
self.SetSize((350, 150))
self.qtyField = wx.TextCtrl(self.panel, wx.ID_ANY, "", style=wx.TE_CENTER)
self.qtyField.SetFocus()
self.longRb = wx.RadioButton(self.panel, wx.ID_ANY, "This", style=wx.RB_GROUP)
self.shortRb = wx.RadioButton(self.panel, wx.ID_ANY, "That")
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
vertSizer = wx.BoxSizer(wx.VERTICAL)
horSizer1 = wx.GridSizer(1, 2, 0, 0)
rbSizer = wx.GridSizer(1, 2, 0, 36)
qtyLabel = wx.StaticText(self.panel, wx.ID_ANY, "Label")
horSizer1.Add(qtyLabel, 0, wx.ALIGN_CENTER, 0)
horSizer1.Add(self.qtyField, 0, wx.ALIGN_CENTER_VERTICAL, 0)
vertSizer.Add(horSizer1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 6)
static_line_1 = wx.StaticLine(self.panel, wx.ID_ANY)
vertSizer.Add(static_line_1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 6)
rbSizer.Add(self.longRb, 0, wx.ALIGN_CENTER, 0)
rbSizer.Add(self.shortRb, 0, wx.ALIGN_CENTER, 0)
vertSizer.Add(rbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 6)
self.SetSizer(vertSizer)
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
# end of class MyApp
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()

two BoxSizers interfere

I have two BoxSizers, the first one
sizer = wx.BoxSizer (wx.VERTICAL)
sizer.Add (self.grid2, 1, wx.EXPAND)
panel2.SetSizer (sizer)
and another vertical BoxSizers, to the left of the button grid, both BoxSizers interfere.
vbox1 = wx.FlexGridSizer (rows = 1, cols = 3, hgap = 5, vgap = 5)
buttonsBox1 = wx.BoxSizer (wx.VERTICAL)
buttonsBox1.Add (self.buttonoborved)
vbox1.Add (buttonsBox1)
vbox1.Add (self.grid2)
vbox1.Add (midPan1, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
panel2.SetSizer (vbox1)
An error occurs - Adding a window already in a sizer, detach it first!
How can they be called at the same time.
Edit:
That are two BoxSizer, one in other, but how can be put buttons in there.
import wx
import wx.grid
from wx.lib.scrolledpanel import ScrolledPanel
class TestPanel(ScrolledPanel):
def __init__(self, parent):
ScrolledPanel.__init__(self, parent, wx.ID_ANY, size=(640, 480))
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self._create_table(), 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(self.sizer)
self.SetupScrolling()
self.SetAutoLayout(1)
def _create_table(self):
_table = wx.grid.Grid(self, -1)
_table.CreateGrid(0, 2)
for i in range(1723): # Work normally If I use 1722 rows
_table.AppendRows()
_table.SetCellValue(i, 0, str(i))
return _table
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
title="Scroll table", size=(640, 480))
self.fSizer = wx.BoxSizer(wx.VERTICAL)
self.fSizer.Add(TestPanel(self), 1, wx.EXPAND)
self.SetSizer(self.fSizer)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
It depends where you want to place the buttons but let's assume they should be at the bottom.
import wx
import wx.grid
from wx.lib.scrolledpanel import ScrolledPanel
class TestPanel(ScrolledPanel):
def __init__(self, parent):
ScrolledPanel.__init__(self, parent, wx.ID_ANY, size=(640, 480))
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self._create_table(), 1, wx.EXPAND | wx.ALL, 5)
self.b1 = wx.Button(self, -1, "Button 1")
self.b2 = wx.Button(self, -1, "Button 2")
self.b3 = wx.Button(self, -1, "Button 3")
button_sizer = wx.BoxSizer(wx.HORIZONTAL)
button_sizer.Add(self.b1)
button_sizer.Add(self.b2)
button_sizer.Add(self.b3)
self.sizer.Add(button_sizer)
self.SetSizer(self.sizer)
self.SetupScrolling()
self.SetAutoLayout(1)
def _create_table(self):
_table = wx.grid.Grid(self, -1)
_table.CreateGrid(0, 2)
for i in range(1723): # Work normally If I use 1722 rows
_table.AppendRows()
_table.SetCellValue(i, 0, str(i))
return _table
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
title="Scroll table", size=(640, 480))
self.fSizer = wx.BoxSizer(wx.VERTICAL)
self.fSizer.Add(TestPanel(self), 1, wx.EXPAND)
self.SetSizer(self.fSizer)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()

Notebook widgets do not display properly unless we resize the window in wxPython?

im having a little issue with NoteBook switching. When I switch notebook tabs, I will need to resize to make the wigdets display properly. I tried using self.Refresh() but that does not seem to do anything. If you have trouble understanding me, please run the following code, then switch tabs and resize, you will notice that there is problems, displaying things correctly. I do not know if this is a problem with wxPython but I think it is with my code.
IMAGE_NAME = []
IMAGE_DATA = []
IMAGEMORE_NAME=[]
IMAGEMORE_DATA=[]
import sys
import wx
def deletepic(self):
try:
self.parent.bitmap.Destroy()
except:
print sys.exc_info()
def sendnewpic(self):
if self.parent.bitmap: deletepic(self)
if IMAGE_DATA[self.image_listsel] != '':
try:
print IMAGE_DATA[self.image_listsel]
bmp = wx.Image(IMAGE_DATA[self.image_listsel], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.parent.scroll_img.SetScrollbars(1, 1, bmp.GetWidth(), bmp.GetHeight())
self.parent.bitmap = wx.StaticBitmap(self.parent.scroll_img, -1, bmp, (0, 0))
self.parent.Refresh()
except:
pass
def areachange(self, pg):
print pg
try:
if IMAGE_DATA[self.image_listsel] == '':
deletepic(self)
except:
pass
if pg == "Regular Pictures":
self.images_area.Show()
self.scroll_img.Show()
self.btnTwo.Show()
else:
self.images_area.Hide()
self.scroll_img.Hide()
self.btnTwo.Hide()
if pg == "More Pictures":
self.images_area.Show()
self.scroll_img.Show()
self.imageboxersiz.Show()
else:
self.imageboxersiz.Hide()
self.Refresh()
class imageTab(wx.Panel):
def __init__(self, parent, grandparent):
wx.Panel.__init__(self, parent)
self.parent = grandparent
self.image_listsel = 0
self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGE_NAME, style=wx.LB_SINGLE)
self.sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.sizerMain = wx.BoxSizer()
self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
btn = wx.Button(self, label="Create New",size=(200, 40))
btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
btn.Bind(wx.EVT_BUTTON, self.newAddImage)
self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
btnSizer.Add(btn, 0, wx.ALL, 5)
btnSizer.Add(btnTwo, 0, wx.ALL, 5)
self.sizer.Add(btnSizer)
self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
self.SetSizer(self.sizerMain)
def imagesel(self, evt):
self.image_listsel = self.listBox.GetSelection()
sendnewpic(self)
def newAddImage(self, evt):
IMAGE_NAME.append('hi')
IMAGE_DATA.append('')
self.listBox.Set(IMAGE_NAME)
self.listBox.SetSelection(len(IMAGE_NAME)-1)
self.imagesel(None) #making it a selected image, globally
def reName(self,parent):
sel = self.listBox.GetSelection()
text = self.listBox.GetString(sel)
renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
if renamed != '':
IMAGE_NAME.pop(sel)
IMAGE_NAME.insert(sel,renamed)
self.listBox.Set(IMAGE_NAME)
self.listBox.SetSelection(sel)
class objectTab(wx.Panel):
def __init__(self, parent, grandparent):
wx.Panel.__init__(self, parent)
self.parent = grandparent
self.image_listsel = 0
self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGEMORE_NAME, style=wx.LB_SINGLE)
self.sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.sizerMain = wx.BoxSizer()
self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
btn = wx.Button(self, label="Create New",size=(200, 40))
btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
btn.Bind(wx.EVT_BUTTON, self.newAddImage)
self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
btnSizer.Add(btn, 0, wx.ALL, 5)
btnSizer.Add(btnTwo, 0, wx.ALL, 5)
self.sizer.Add(btnSizer)
self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
self.SetSizer(self.sizerMain)
def imagesel(self, evt):
self.image_listsel = self.listBox.GetSelection()
def newAddImage(self, evt):
IMAGEMORE_NAME.append('New image')
IMAGEMORE_DATA.append('')
self.listBox.Set(IMAGEMORE_NAME)
self.listBox.SetSelection(len(IMAGEMORE_NAME)-1)
self.imagesel(None) #making it a selected image, globally
def reName(self,parent):
sel = self.listBox.GetSelection()
text = self.listBox.GetString(sel)
renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
if renamed != '':
IMAGEMORE_NAME.pop(sel)
IMAGEMORE_NAME.insert(sel,renamed)
self.listBox.Set(IMAGEMORE_NAME)
self.listBox.SetSelection(sel)
class MyPanel(wx.Panel):
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self, *args, **kwargs)
self.notebook = wx.Notebook(self, size=(225, -1))
self.tab_images = imageTab(self.notebook, self)
self.notebook.AddPage(self.tab_images, "Regular Pictures", select=True)
self.tab_imagesmore = objectTab(self.notebook, self)
self.notebook.AddPage(self.tab_imagesmore, "More Pictures")
self.scroll_img = wx.ScrolledWindow(self, -1)
self.scroll_img.SetScrollbars(1, 1, 600, 400)
self.images_area = wx.StaticBox(self, -1, '')
self.sizerBox = wx.StaticBoxSizer(self.images_area, wx.HORIZONTAL)
self.sizerBox2 = wx.BoxSizer()
self.sizerBox.Add(self.scroll_img, 1, wx.EXPAND|wx.ALL, 10)
self.sizerBox2.Add(self.sizerBox, 1, wx.EXPAND|wx.ALL, 10)
self.sizer = wx.BoxSizer()
self.sizer.Add(self.notebook, proportion=0, flag=wx.EXPAND)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.btnTwo = wx.Button(self, label="Load File", size=(200, 40))
self.bmp = None
self.bitmap = None
self.imageboxersiz=wx.ComboBox(self, -1, "None Selected!",(0, 0), (190,20),IMAGE_NAME, wx.CB_DROPDOWN)
btnSizer.Add(self.imageboxersiz, 0, wx.TOP, 15)
btnSizer.Add(self.btnTwo, 0, wx.TOP, 15)
self.sizerBox2.Add(btnSizer)
#
self.sizer.Add(self.sizerBox2, proportion=1, flag=wx.EXPAND)
self.SetSizer(self.sizer)
self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
areachange(self, self.notebook.GetPageText(0))
def OnClickTop(self, event):
self.scroll_img.Scroll(600, 400)
def OnClickBottom(self, event):
self.scroll_img.Scroll(1, 1)
def OnPageChanged(self, event):
new = event.GetSelection()
areachange(self, self.notebook.GetPageText(new))
event.Skip()
def OnPageChanging(self, event):
event.Skip()
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = MyPanel(self)
self.Show()
app = wx.App(False)
win = MainWindow(None, size=(600, 400))
app.MainLoop()
Thank you very much.
Just change the self.Refresh() to self.Layout(). Worked for me on Windows 7 anyway.

Categories

Resources