Cannot clear content of wxBoxSizer - python

For some reason my sizer.Clear() does not seem to work properly.
As far as I have understood from the docs it should work.
Am I doing something wrong that causes this behavior?
import wx
import os
import sys
import time
import string
import urllib2
class MainWindow(wx.Frame):
def __init__(self, parent, id=wx.ID_ANY, title="", pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.MINIMIZE_BOX | wx.CLOSE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(sizer)
self.sizer = sizer
self.panel = panel
self.ShowLoginBox()
def ShowLoginBox(self):
sizer = wx.FlexGridSizer(rows=4, cols=2, hgap=15, vgap=10)
sizer.AddGrowableCol(1, 1)
login_url = wx.TextCtrl(self.panel, 1, size=(150, -1))
label_url = wx.StaticText(self.panel, -1, "URL:")
sizer.Add(label_url, 0, wx.LEFT | wx.TOP| wx.RIGHT, 30)
sizer.Add(login_url, 1, wx.EXPAND | wx.TOP | wx.RIGHT, 30)
login_username = wx.TextCtrl(self.panel, 1, size=(150, -1))
label_username = wx.StaticText(self.panel, -1, "Username:")
sizer.Add(label_username, 0, wx.LEFT | wx.RIGHT, 30)
sizer.Add(login_username, 1, wx.EXPAND | wx.RIGHT, 30)
login_password = wx.TextCtrl(self.panel, 1, size=(150, -1), style=wx.TE_PASSWORD)
label_password = wx.StaticText(self.panel, -1, "Password:")
sizer.Add(label_password, 0, wx.LEFT | wx.RIGHT, 30)
sizer.Add(login_password, 1, wx.EXPAND | wx.RIGHT, 30)
btn_process = wx.Button(self.panel, -1, "&Login")
self.panel.Bind(wx.EVT_BUTTON, self.OnSubmit, btn_process)
sizer.Add(btn_process, 0, wx.LEFT, 30)
login_url.SetValue("http://example.com")
login_username.SetValue("admin")
login_password.SetValue("pass")
self.login_url = login_url
self.login_username = login_username
self.login_password = login_password
self.sizer.Clear()
self.sizer.Add(sizer, 1, wx.EXPAND)
self.SetSizeWH(330, 250)
self.Center()
def OnSubmit(self, event):
user_url = self.login_url.GetValue()
user_name = self.login_username.GetValue()
user_pass = self.login_password.GetValue()
# login info is used to get a URL
print user_url, user_name, user_pass
# if 200 OK
self.ShowNew()
def ShowNew(self):
sizer = wx.BoxSizer(wx.HORIZONTAL)
content = wx.ListCtrl(self.panel, -1, size=(780, 400), style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_HRULES | wx.LC_VRULES)
content.InsertColumn(0, 'URL', width=745)
sizer.Add(content, 1, wx.EXPAND)
# populate with data from URL
self.SetSizeWH(800, 520)
self.Center()
self.sizer.Clear()
self.sizer.Add(sizer)
if __name__ == '__main__':
home_path = os.path.dirname(os.path.realpath(__file__))
app = wx.PySimpleApp()
frame = MainWindow(None, title="Test", size=(800, 520))
frame.SetBackgroundColour("#ffffff")
frame.Show()
app.MainLoop()

Use sizer.Clear(True) instead of sizer.Clear() and it should work.
The explanation
If the parameter sent to Clear() method is True, "then child windows will also be deleted" (http://docs.wxwidgets.org/2.8/wx_wxsizer.html#wxsizerclear).
You want to clear the children of wxSizer: wxStaticText, wxTextCtrl, wxButton, which are all derived from wxControl and wxWindow. That's why the sizer must know that you want to remove also the child windows.
See also: http://docs.wxwidgets.org/2.8/wx_wxstatictext.html, http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html and http://docs.wxwidgets.org/2.8/wx_wxbutton.html .
Cheers!

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

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()

How to change the value of an existing wxPython object with a file dialog button

I have been working on creating a python GUI for some work. I would self-describe as a novice when it comes to by Python knowledge. I am using wxPython and wxGlade to help with the GUI development, as well.
The problem is as follows:
I have an empty TextCtrl object and a Button next to it.
The Button is meant to open a FileDialog and populate or replace the TextCtrl with the value of the file location that is selected. I have created the functionality for the button to open the FileDialog but I can't seem to figure out how to populate the TextCtrl with that resulting value.
import wx
class frmCheckSubmital(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: frmCheckSubmitall.__init__
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.rbxUtilitySelect = wx.RadioBox(self, wx.ID_ANY, "Utility", choices=["Stormwater", "Sewer", "Water"], majorDimension=1, style=wx.RA_SPECIFY_ROWS)
self.txtFeaturesPath = wx.TextCtrl(self, wx.ID_ANY, "")
self.btnSelectFeatures = wx.Button(self, wx.ID_ANY, "Select")
# selectEvent = lambda event, pathname=txt: self.dialogFeatures(event, pathname)
self.btnSelectFeatures.Bind(wx.EVT_BUTTON, self.dialogFeatures)
self.txtPipesPath = wx.TextCtrl(self, wx.ID_ANY, "")
self.btnSelectPipes = wx.Button(self, wx.ID_ANY, "Select")
self.bxOutput = wx.Panel(self, wx.ID_ANY)
self.cbxDraw = wx.CheckBox(self, wx.ID_ANY, "Draw")
self.btnClear = wx.Button(self, wx.ID_ANY, "Clear")
self.btnZoom = wx.Button(self, wx.ID_ANY, "Zoom")
self.btnRun = wx.Button(self, wx.ID_ANY, "Run", style=wx.BU_EXACTFIT)
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: frmCheckSubmitall.__set_properties
self.SetTitle("Check Submittal")
self.rbxUtilitySelect.SetSelection(0)
self.btnSelectFeatures.SetMinSize((80, 20))
self.btnSelectPipes.SetMinSize((80, 20))
self.cbxDraw.SetValue(1)
self.btnClear.SetMinSize((50, 20))
self.btnZoom.SetMinSize((50, 20))
# end wxGlade
def __do_layout(self):
# begin wxGlade: frmCheckSubmitall.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_5 = wx.BoxSizer(wx.VERTICAL)
sizer_8 = wx.BoxSizer(wx.HORIZONTAL)
sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
sizer_5.Add(self.rbxUtilitySelect, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10)
lblFeatures = wx.StaticText(self, wx.ID_ANY, "Features: ")
sizer_6.Add(lblFeatures, 0, wx.ALIGN_CENTER | wx.LEFT, 16)
sizer_6.Add(self.txtFeaturesPath, 1, 0, 0)
sizer_6.Add(self.btnSelectFeatures, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
sizer_5.Add(sizer_6, 0, wx.EXPAND, 0)
lblPipes = wx.StaticText(self, wx.ID_ANY, "Pipes: ")
sizer_7.Add(lblPipes, 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT, 16)
sizer_7.Add(self.txtPipesPath, 1, 0, 0)
sizer_7.Add(self.btnSelectPipes, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5)
sizer_5.Add(sizer_7, 0, wx.ALL | wx.EXPAND, 0)
sizer_5.Add(self.bxOutput, 1, wx.ALL | wx.EXPAND, 10)
sizer_8.Add(self.cbxDraw, 0, wx.LEFT | wx.RIGHT, 10)
sizer_8.Add(self.btnClear, 0, wx.RIGHT, 10)
sizer_8.Add(self.btnZoom, 0, 0, 0)
sizer_8.Add((20, 20), 1, 0, 0)
sizer_8.Add(self.btnRun, 0, wx.BOTTOM | wx.RIGHT, 10)
sizer_5.Add(sizer_8, 0, wx.EXPAND, 0)
sizer_1.Add(sizer_5, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
self.SetSize((400, 300))
# end wxGlade
# Begin Dialog Method
def dialogFeatures(self, event):
# otherwise ask the user what new file to open
#with wx.FileDialog(self, "Select the Features File", wildcard="Text files (*.txt)|*.txt",
# style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
fileDialog = wx.FileDialog(self, "Select the Features File", wildcard="Text files (*.txt)|*.txt",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
self.txtFeaturesPath.SetValue = pathname
self.txtFeaturesPath.SetValue(pathname)
try:
with open(pathname, 'r') as file:
self.txtFeaturesPath = file
except IOError:
wx.LogError("Cannot open file '%s'." % newfile)
# End Dialog Method
# end of class frmCheckSubmitall
if __name__ == '__main__':
app=wx.PySimpleApp()
frame = frmCheckSubmital(parent=None, id=-1)
frame.Show()
app.MainLoop()
I've tried to do several things and I am just burnt out and in need of some help.
Some things I've tried to do:
- Add a third argument in the dialog method to return that (just not sure where to assign)
- Use a lambda event to try and assign the value with the constructors?
Any help or insight would be greatly appreciated. Thank you!
As others have already pointed out, the way to go is by using the text control's SetValue. But here's a small runnable example:
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
open_file_dlg_btn = wx.Button(self, label="Open FileDialog")
open_file_dlg_btn.Bind(wx.EVT_BUTTON, self.on_open_file)
self.file_path = wx.TextCtrl(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(open_file_dlg_btn, 0, wx.ALL, 5)
sizer.Add(self.file_path, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def on_open_file(self, event):
wildcard = "Python source (*.py)|*.py|" \
"All files (*.*)|*.*"
dlg = wx.FileDialog(
self, message="Choose a file",
defaultDir='',
defaultFile="",
wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_MULTIPLE | wx.FD_CHANGE_DIR
)
if dlg.ShowModal() == wx.ID_OK:
paths = dlg.GetPath()
print("You chose the following file(s):")
for path in paths:
print(path)
self.file_path.SetValue(str(paths))
dlg.Destroy()
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None,
title="File Dialogs Tutorial")
panel = MyPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Try:
self.txtFeaturesPath.SetValue(pathname)
You have a few other buggy "features" in your example code, so watch out.
I realized that what I was assigning was not the value the fileDialog opens, but was instead the location in ram of the fileDialog object.
the solution was the following
value = fileDialog.Directory + "\\" + fileDialog.filename
self.txtFeaturesPath.SetValue(value)
thank you!

Why does this wxPython GUI freeze when self.Destroy() is used instead of self.Close()? (example attached)

LoginDialog is opened with self.loginButton, and upon closing it, the GUI freezes; the login button remains pressed, and there are only alert sounds when attempting to click on anything.
LoginDialog() was from this tutorial, just augmented with the file-write line in onLogin (which isn't the problem source). All appears to work when switching from self.Destroy() to self.Close().
wxPython version is 3.0, Python 2.7.10
The following code is a working example of the issue:
import wx
# wxGlade dependency
import gettext
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.updateLoginButton = wx.Button(self, wx.ID_ANY, _("Store/Update Login"))
self.Bind(wx.EVT_BUTTON, self.updateLogin, self.updateLoginButton)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle(_("Dialog Test"))
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_1 = wx.FlexGridSizer(3, 1, 1, 0)
exportButtons_sizer = wx.FlexGridSizer(1, 1, 1, 10)
exportButtons_sizer.Add(self.updateLoginButton, 0, wx.TOP | wx.ALIGN_CENTER, 15)
grid_sizer_1.Add(exportButtons_sizer, 0, wx.TOP | wx.ALIGN_CENTER, 20)
sizer_1.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 15)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
self.Layout()
def updateLogin(self, event):
dlg = LoginDialog(self, -1)
dlg.ShowModal()
class MyApp(wx.App):
def OnInit(self):
frame_1 = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(frame_1)
frame_1.Show()
return True
class LoginDialog(wx.Dialog):
"""
Class to define login dialog
"""
# ----------------------------------------------------------------------
def __init__(self, parent, id, title="Update Login Info"):
"""Constructor"""
wx.Dialog.__init__(self, parent, id, title)
# user info
user_sizer = wx.BoxSizer(wx.HORIZONTAL)
user_lbl = wx.StaticText(self, label="Username:")
user_sizer.Add(user_lbl, 0, wx.ALL | wx.CENTER, 5)
self.user = wx.TextCtrl(self)
user_sizer.Add(self.user, 0, wx.ALL, 5)
# pass info
p_sizer = wx.BoxSizer(wx.HORIZONTAL)
p_lbl = wx.StaticText(self, label="Password:")
p_sizer.Add(p_lbl, 0, wx.ALL | wx.CENTER, 5)
self.password = wx.TextCtrl(self, style=wx.TE_PASSWORD | wx.TE_PROCESS_ENTER)
p_sizer.Add(self.password, 0, wx.ALL, 5)
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(user_sizer, 0, wx.ALL, 5)
main_sizer.Add(p_sizer, 0, wx.ALL, 5)
btn = wx.Button(self, label="OK")
btn.Bind(wx.EVT_BUTTON, self.onLogin)
main_sizer.Add(btn, 0, wx.ALL | wx.CENTER, 5)
self.SetSizer(main_sizer)
self.__set_properties()
# ----------------------------------------------------------------------
def onLogin(self, event):
"""
Check credentials and login
"""
password = self.password.GetValue()
email = self.user.GetValue()
with open('login.txt', 'w') as f:
f.write(email + ', ' + password)
self.Destroy()
def __set_properties(self):
self.user.SetMinSize((220, 20))
if __name__ == "__main__":
gettext.install("app")
app = MyApp(0)
app.MainLoop()
If a dialog is intended to be used with ShowModal dialog then the dialog should call EndModal when it is done, and the caller should be the one who calls Destroy after it has fetched values from the dialog if needed.

wxPython layout using boxsizers

I've recently started using wxPython to build a GUI and I'm trying to create the following layout:
Button1 Button2 Button3
----------------------------------------
listbox | textctrl
The buttons should have a flexible width, expanding to fill the full width of the frame with a border between them (each buttons has a width (incl. border) of 1/3 frame). Their height should be set to a height in pixels.
The listbox should fill the frame vertically and have a set width of x pixels
The textctrol should be a textbox which expands to fill the width of the frame vertically as well as horizontally.
This is the code I have:
mainPanel = wx.Panel(self, -1)
parentBox = wx.BoxSizer(wx.VERTICAL)
menubar = wx.MenuBar()
filem = wx.Menu()
menubar.Append(filem, '&File')
self.SetMenuBar(menubar)
navPanel = wx.Panel(mainPanel, -1, size=(1000, 80))
navBox = wx.BoxSizer(wx.HORIZONTAL)
newSection = wx.Button(navPanel, self.ID_NEW, 'New')
renSection = wx.Button(navPanel, self.ID_RENAME, 'Rename')
dltSection = wx.Button(navPanel, self.ID_DELETE, 'Delete')
navBox.Add(newSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(renSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(dltSection, 1, wx.EXPAND | wx.ALL, 5)
navPanel.SetSizer(navBox)
contentPanel = wx.Panel(mainPanel, -1, size=(1000, 600))
contentBox = wx.BoxSizer(wx.HORIZONTAL)
self.listbox = wx.ListBox(contentPanel, -1, size=(300, 700))
self.settings = wx.TextCtrl(contentPanel, -1)
contentBox.Add(self.listbox, 0)
contentBox.Add(self.settings, 1, wx.EXPAND | wx.ALL, 5)
contentPanel.SetSizer(contentBox)
parentBox.Add(navPanel, 0, wx.EXPAND | wx.ALL, 5)
parentBox.Add(contentPanel, 1, wx.EXPAND | wx.ALL, 5)
mainPanel.SetSizer(parentBox)
Something is going wrong since what I see is not what I expect to see, anybody who can help me out?
It is working for me, I'm on win64, python 32bit 2.7.3.3, wx '2.8.12.1 (msw-unicode)'. The full working test example is:
import wx
class testframe(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'some title')
mainPanel = wx.Panel(self, -1)
parentBox = wx.BoxSizer(wx.VERTICAL)
menubar = wx.MenuBar()
filem = wx.Menu()
menubar.Append(filem, '&File')
self.SetMenuBar(menubar)
navPanel = wx.Panel(mainPanel, -1, size=(1000, 80))
navBox = wx.BoxSizer(wx.HORIZONTAL)
newSection = wx.Button(navPanel, -1, 'New')
renSection = wx.Button(navPanel, -1, 'Rename')
dltSection = wx.Button(navPanel, -1, 'Delete')
navBox.Add(newSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(renSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(dltSection, 1, wx.EXPAND | wx.ALL, 5)
navPanel.SetSizer(navBox)
contentPanel = wx.Panel(mainPanel, -1, size=(1000, 600))
contentBox = wx.BoxSizer(wx.HORIZONTAL)
self.listbox = wx.ListBox(contentPanel, -1, size=(300, 700))
self.settings = wx.TextCtrl(contentPanel, -1)
contentBox.Add(self.listbox, 0, wx.ALL, 5)
contentBox.Add(self.settings, 1, wx.EXPAND | wx.ALL, 5)
contentPanel.SetSizer(contentBox)
parentBox.Add(navPanel, 0, wx.EXPAND | wx.ALL, 5)
parentBox.Add(contentPanel, 1, wx.EXPAND | wx.ALL, 5)
mainPanel.SetSizer(parentBox)
parentBox.Fit(self)
app = wx.PySimpleApp()
app.frame = testframe()
app.frame.Show()
app.MainLoop()
Notice the addition of Fit() of the main sizer, and also 5px border added to the listbox.

Categories

Resources