I am almost done my wxPython soundboard and want to implement one quick feature.
How does one add another panel to a wxPython window, and how do you implement the text, [ NOW PLAYING ] within that panel.
Here is my code so far:
import wx
import os
import pygame
pygame.init()
##SOUNDS##
##SOUNDS##
class windowClass(wx.Frame):
__goliathwav = pygame.mixer.Sound("goliath.wav")
__channelopen = pygame.mixer.Sound("channelopen.wav")
def __init__(self, *args, **kwargs):
super(windowClass,self).__init__(*args,**kwargs)
self.__basicGUI()
def __basicGUI(self):
panel = wx.Panel(self)
menuBar = wx.MenuBar()
fileButton = wx.Menu()
aboutButton = wx.Menu()
exitItem = fileButton.Append(wx.ID_EXIT, 'Exit','status msg...')
aboutItem = aboutButton.Append(wx.ID_ABOUT, "About")
menuBar.Append(fileButton, 'File')
menuBar.Append(aboutButton, 'About this program')
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.__quit, exitItem)
self.Bind(wx.EVT_MENU, self.__onmenuhelpabout, aboutItem)
self.__sound_dict = { "Goliath" : self.__goliathwav,
"Goliath2" : self.__channelopen
}
self.__sound_list = sorted(self.__sound_dict.keys())
self.__list = wx.ListBox(panel,pos=(20,20), size=(250,150))
for i in self.__sound_list:
self.__list.Append(i)
self.__list.Bind(wx.EVT_LISTBOX,self.__on_click)
textarea = wx.TextCtrl(self, -1,
style=wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|
wx.TE_RICH2, size=(250,150))
self.usertext = textarea
#self.__list2 = wx.ListBox(panel,pos=(19.5,180), size=(251,21)) #second panel
#for j in self.__sound_list:
# self.__list2.Append(i)
#self.__list2.Bind(wx.EVT_LISTBOX,self.__on_click)
#wx.TextCtrl(panel,pos=(10,10), size=(250,150))
self.SetTitle("Soundboard")
self.Show(True)
def __onmenuhelpabout(self,event):
dialog = wx.Dialog(self, -1, "[Soundboard]") # ,
#style=wx.DIALOG_MODAL | wx.STAY_ON_TOP)
dialog.SetBackgroundColour(wx.WHITE)
panel = wx.Panel(dialog, -1)
panel.SetBackgroundColour(wx.WHITE)
panelSizer = wx.BoxSizer(wx.VERTICAL)
boldFont = wx.Font(panel.GetFont().GetPointSize(),
panel.GetFont().GetFamily(),
wx.NORMAL,wx.BOLD)
lab1 = wx.StaticText(panel, -1, " SOUNDBOARD ")
lab1.SetFont(wx.Font(36,boldFont.GetFamily(), wx.ITALIC, wx.BOLD))
lab1.SetSize(lab1.GetBestSize())
imageSizer = wx.BoxSizer(wx.HORIZONTAL)
imageSizer.Add(lab1, 0, wx.ALL | wx.ALIGN_CENTRE_VERTICAL, 5)
lab2 = wx.StaticText(panel, -1, "Created by youonlylegoonce(cyrex)(Kommander000) for the glory " + \
"of the republic.")
panelSizer.Add(imageSizer, 0, wx.ALIGN_CENTRE)
panelSizer.Add((10, 10)) # Spacer.
panelSizer.Add(lab2, 0, wx.ALIGN_CENTRE)
panel.SetAutoLayout(True)
panel.SetSizer(panelSizer)
panelSizer.Fit(panel)
topSizer = wx.BoxSizer(wx.HORIZONTAL)
topSizer.Add(panel, 0, wx.ALL, 10)
dialog.SetAutoLayout(True)
dialog.SetSizer(topSizer)
topSizer.Fit(dialog)
dialog.Centre()
btn = dialog.ShowModal()
dialog.Destroy()
def __on_click(self,event):
event.Skip()
name = self.__sound_list[self.__list.GetSelection()]
sound = self.__sound_dict[name]
print("[ NOW PLAYING ] ... %s" % name)
pygame.mixer.Sound.play(sound)
def __quit(self, e):
self.Close()
def main():
app = wx.App()
windowClass(None, -1, style=wx.MAXIMIZE_BOX | wx.CAPTION | wx.CENTRE)
app.MainLoop()
main()
Before:
print("[ NOW PLAYING ] ... %s" % name)
input:
self.usertext.SetValue("[ NOW PLAYING ] ... %s" % name)
P.S. Your indentation is a mess
Related
Problem: I want to be able to force the scrollbar to the bottom when I call createNewRow(). I can see that the self.Scroll(0, self.scrollRange) is occurring in OnKeyTyped() and the scrollbar moves to the bottom of the window but then the scrollbar moves to the top of the window again. I tried to stop this by binding wx.EVT_SCROLLWIN to OnScroll which calls event.Skip() but it appears that this has not worked. I am out of ideas on how to proceed as I don't know enough about eventHandlers and scroll events in wxPython. Any help on how to proceed would be much appreciated. Full code below.
import os
import wx
import datetime as dt
import wx.lib.scrolledpanel as scrolled
class MyFrame(wx.Frame):
width = 1000
height = 600
today = dt.date.today()
today_date = f"{today:%A - %d %B %Y}"
filename = f"Worklog {today_date}"
wxTHICK_LINE_BORDER = 3
def __init__(self, parent=None, title=filename, size=(width,height - 1)):
wx.Frame.__init__(self, parent=parent, title=title, size=size)
self.parent = parent
self.title = title
self.size = size
self.BuildMenuBar()
def BuildMenuBar(self):
# Menu bar
self.menuBar = wx.MenuBar()
self.fileMenu = wx.Menu()
self.NewOpt = wx.MenuItem(self.fileMenu, wx.ID_NEW, '&New\tCtrl+N')
self.OpenOpt = wx.MenuItem(self.fileMenu, wx.ID_OPEN, '&Open\tCtrl+O')
self.SaveOpt = wx.MenuItem(self.fileMenu, wx.ID_SAVE, '&Save\tCtrl+S')
self.QuitOpt = wx.MenuItem(self.fileMenu, wx.ID_EXIT, '&Quit\tCtrl+Q')
self.fileMenu.Append(self.NewOpt)
self.fileMenu.Append(self.OpenOpt)
self.fileMenu.Append(self.SaveOpt)
self.fileMenu.Append(self.QuitOpt)
self.Bind(wx.EVT_MENU, self.OnQuit, self.QuitOpt)
self.menuBar.Append(self.fileMenu, '&File')
self.SetMenuBar(self.menuBar)
def OnQuit(self, e):
self.Close()
class MyPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self, parent=parent)
self.parent = parent
self.size = parent.size
panel_colour = wx.Colour(240, 240, 240, 255)
self.SetBackgroundColour(panel_colour)
self.Refresh()
class MyScrolledPanel(scrolled.ScrolledPanel):
def __init__(self, parent):
scrolled.ScrolledPanel.__init__(self, parent=parent, style = wx.TAB_TRAVERSAL | wx.TB_BOTTOM)
self.parent = parent
# self.size = parent.size
self.width = parent.size[0]
self.height = parent.size[1]
scrollpanel_colour = wx.Colour(255, 255, 255, 255)
self.SetBackgroundColour(scrollpanel_colour)
# Call a refresh to update the UI
self.Refresh()
self.SetAutoLayout(True)
self.SetupScrolling()
self.InitUI()
self.Bind(wx.EVT_SCROLLWIN, self.OnScroll, self)
self.Bind(wx.EVT_SIZE, self.OnSize, self)
def OnScroll(self, e):
e.Skip()
def InitUI(self):
vgap = 0
hgap = 0
self.rowList = []
self.n = 0
self.scrollSizer = wx.GridBagSizer(vgap + 10, hgap + 10)
self.row = self.CreateNewRow(self.n)
self.rowList.append(self.row)
print(f"Row List: {self.rowList[-1]}")
self.scrollSizer.Add(self.row[0], pos = (self.i, 0), flag = wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, border = 10)
self.scrollSizer.Add(self.row[1], pos = (self.i, 1), flag = wx.EXPAND | wx.TOP | wx.RIGHT | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL , border = 10)
self.scrollSizer.AddGrowableCol(1)
self.SetSizer(self.scrollSizer)
self.panelSizer = wx.GridBagSizer(vgap, hgap)
self.panelSizer.AddGrowableRow(0)
self.panelSizer.AddGrowableCol(0)
self.panelSizer.Add(self, pos = (0, 0), flag = wx.EXPAND, border = 0) # Add wx.Window not wx.Sizer
self.parent.SetSizer(self.panelSizer)
def CreateNewRow(self, number):
self.i = number
self.txtStr = "%02d" % (self.i+1) + ". "
self.staticText = wx.StaticText(self, wx.ID_ANY, self.txtStr)
#pos = (x, y)
#self.staticText.SetForegroundColour(wx.Colour(0,0,0))
self.control = wx.TextCtrl(self, self.i)
self.control.SetMaxLength(256)
self.text_history_length = 0
self.control.Bind(wx.EVT_TEXT, self.OnKeyTyped, id = self.i)
#self.control = wx.TextCtrl(self, -1, pos = (x + w + 5,y) )
#style = wx.TE_MULTILINE
elems = [self.staticText, self.control]
return elems
def OnSize(self, e):
self.width, self.height = e.GetSize()
self.SetSize((self.width, self.height))
self.OnSizeChange()
self.Refresh()
def OnSizeChange(self):
# Fit child elements
self.scrollSizer.FitInside(self)
# Resize layout
self.Layout()
# Resize scrolling
self.SetupScrolling()
def OnKeyTyped(self, e):
self.text_length = len(e.GetString())
if (self.text_history_length == 1 and self.text_length == 0):
print(f"History length: {self.text_history_length}")
print(f"Text length: {self.text_length}")
self.text_history_length = self.text_length
pass
elif (self.text_history_length == 0 and self.text_length == 1):
print(f"History length: {self.text_history_length}")
print(f"Text length: {self.text_length}")
self.n += 1
self.row = self.CreateNewRow(self.n)
print(f"Action: {self.row}")
print(f"Row List: {self.rowList[-1]}")
self.rowList.append(self.row)
self.scrollSizer.Add(self.row[0], pos = (self.n, 0), flag = wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, border = 10)
self.scrollSizer.Add(self.row[1], pos = (self.n, 1), flag = wx.EXPAND | wx.TOP | wx.RIGHT | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL , border = 10)
self.SetupScrolling()
self.text_history_length = self.text_length
self.rowList[self.n-1][1].Bind(wx.EVT_TEXT, None, id = self.n-1)
self.text_history_length = 0
else:
print(f"History length: {self.text_history_length}")
print(f"Text length: {self.text_length}")
self.text_history_length = self.text_length
self.rowList[-1][1].SetFocus()
self.scrolledPanelChild = self.GetChildren()[-1] # [ scrollPanel ]
self.ScrollChildIntoView(self.scrolledPanelChild)
self.OnSizeChange()
self.scrollRange = self.GetScrollRange(wx.VERTICAL)
print(f"ScrollRange: {self.scrollRange}")
#self.scrollUnits = self.GetScrollPixelsPerUnit()
#print(f"ScrollUnit: {self.scrollUnits}")
#self.scrollThumb = self.GetScrollThumb(wx.VERTICAL)
#print(f"ScrollThumb: {self.scrollThumb}")
self.Scroll(0, self.scrollRange)
def main():
app = wx.App(False)
app.locale = wx.Locale(wx.Locale.GetSystemLanguage())
frame = MyFrame()
panel = MyPanel(frame)
scrolledPanel = MyScrolledPanel(panel)
frame.Show(True)
app.MainLoop()
if __name__ == "__main__":
main()
In :
def OnSizeChange(self):
# Fit child elements
self.scrollSizer.FitInside(self)
# Resize layout
self.Layout()
# Resize scrolling
self.SetupScrolling()
the SetupScrolling() event causes the scrollbar to reset to the top of the page. So if you comment this the Scroll(0, self.scrollRange) will scroll the scrollbar to the bottom of the page. Improvement would be to get this call to happen after SetupScrolling so that it happens anyway. Maybe the call to SetupScrolling is not necessary in anycase and Layout() is enough.
Old question but still. This can be solved using:
wx.CallAfter(self._scrolled_panel.ScrollChildIntoView, new_text) Or calling any of the other scroll methods from the CallAfter.
or
SetupScrolling(scrollIntoView=True, scrollToTop=False)
Firstly, this is what I'm trying to make with wxPython. I would like the region labeled "Picture 1" to be able to accept a dragged image, and then when an image is dragged there, be replaced with a thumbnail of that image. I have researched "Drag and Drop" in wxPython, but I can't seem to find the tools needed for me to do this.
Any help getting me started on the right track would be greatly appreciated.
You will want the Pillow package for creating a thumbnail. The other piece you will want is most likely the wx.FileDropTarget class. I ended up doing the following:
import os
import wx
from PIL import Image
from wx.lib.pubsub import pub
PhotoMaxSize = 240
class DropTarget(wx.FileDropTarget):
def __init__(self, widget):
wx.FileDropTarget.__init__(self)
self.widget = widget
def OnDropFiles(self, x, y, filenames):
print(filenames)
image = Image.open(filenames[0])
image.thumbnail((PhotoMaxSize, PhotoMaxSize))
image.save('thumbnail.png')
pub.sendMessage('dnd', filepath='thumbnail.png')
return True
class PhotoCtrl(wx.App):
def __init__(self, redirect=False, filename=None):
wx.App.__init__(self, redirect, filename)
self.frame = wx.Frame(None, title='Photo Control')
self.panel = wx.Panel(self.frame)
pub.subscribe(self.update_image_on_dnd, 'dnd')
self.PhotoMaxSize = 240
self.createWidgets()
self.frame.Show()
def createWidgets(self):
instructions = 'Browse for an image'
img = wx.Image(240,240)
self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.Bitmap(img))
filedroptarget = DropTarget(self)
self.imageCtrl.SetDropTarget(filedroptarget)
instructLbl = wx.StaticText(self.panel, label=instructions)
self.photoTxt = wx.TextCtrl(self.panel, size=(200,-1))
browseBtn = wx.Button(self.panel, label='Browse')
browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY),
0, wx.ALL|wx.EXPAND, 5)
self.mainSizer.Add(instructLbl, 0, wx.ALL, 5)
self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
self.sizer.Add(self.photoTxt, 0, wx.ALL, 5)
self.sizer.Add(browseBtn, 0, wx.ALL, 5)
self.mainSizer.Add(self.sizer, 0, wx.ALL, 5)
self.panel.SetSizer(self.mainSizer)
self.mainSizer.Fit(self.frame)
self.panel.Layout()
def onBrowse(self, event):
"""
Browse for file
"""
wildcard = "JPEG files (*.jpg)|*.jpg"
dialog = wx.FileDialog(None, "Choose a file",
wildcard=wildcard,
style=wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
self.photoTxt.SetValue(dialog.GetPath())
dialog.Destroy()
self.onView()
def update_image_on_dnd(self, filepath):
self.onView(filepath=filepath)
def onView(self, filepath=None):
if not filepath:
filepath = self.photoTxt.GetValue()
img = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
# scale the image, preserving the aspect ratio
W = img.GetWidth()
H = img.GetHeight()
if W > H:
NewW = self.PhotoMaxSize
NewH = self.PhotoMaxSize * H / W
else:
NewH = self.PhotoMaxSize
NewW = self.PhotoMaxSize * W / H
img = img.Scale(NewW,NewH)
self.imageCtrl.SetBitmap(wx.Bitmap(img))
self.panel.Refresh()
if __name__ == '__main__':
app = PhotoCtrl()
app.MainLoop()
This worked for me on Windows 7 with wxPython 4. Note that I am dragging a file from Windows Explorer onto my wxPython application's image widget.
Is it possible to have countdown as per below image either in python or wxpython (Any other library). I have googled but didn't find the same. I have also checked wxpython but it doesn't have same implementation, however it has gauge but that is not what Im looking for. Can anybody please help me to get it done. Thanks.
I'm able to get what I exactly need after googling and little tweaks. My actual requirement is a countdown (timer) with animation. Below is the code that did the trick(Thanks to Andrea Gavana for wonderful work):
Hope it will help someone else looking for the same.
SpeedMeter
My Implementation:
import wx
import wx.lib.buttons
import SpeedMeter as SM
from math import pi, sqrt
class MyFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, -1, "SpeedMeter Demo ;-)",
wx.DefaultPosition,
size=(400,400),
style=wx.DEFAULT_FRAME_STYLE |
wx.NO_FULL_REPAINT_ON_RESIZE)
panel = wx.Panel(self)
self.SpeedWindow = SM.SpeedMeter(panel,
extrastyle=SM.SM_DRAW_HAND |
SM.SM_DRAW_SECTORS |
SM.SM_DRAW_MIDDLE_TEXT |
SM.SM_DRAW_SECONDARY_TICKS |
SM.SM_DRAW_PARTIAL_FILLER |
SM.SM_DRAW_SHADOW
)
# We Want To Simulate A Clock. Somewhat Tricky, But Did The Job
self.SpeedWindow.SetAngleRange(pi/2, 5*pi/2)
intervals = range(0, 13)
self.SpeedWindow.SetIntervals(intervals)
colours = [wx.SystemSettings_GetColour(0)]*12
self.SpeedWindow.SetIntervalColours(colours)
ticks = [str(interval) for interval in intervals]
ticks[-1] = ""
ticks[0] = "12"
self.SpeedWindow.SetTicks(ticks)
self.SpeedWindow.SetTicksColour(wx.BLUE)
self.SpeedWindow.SetTicksFont(wx.Font(11, wx.SCRIPT, wx.NORMAL, wx.BOLD, True))
self.SpeedWindow.SetNumberOfSecondaryTicks(4)
# Set The Colour For The External Arc
self.SpeedWindow.SetArcColour(wx.BLUE)
self.SpeedWindow.SetHandColour(wx.BLACK)
self.SpeedWindow.SetMiddleText("0 s")
self.SpeedWindow.SetMiddleTextColour(wx.RED)
# We Set The Background Colour Of The SpeedMeter OutSide The Control
self.SpeedWindow.SetSpeedBackground(wx.WHITE)
# Set The Colour For The Shadow
self.SpeedWindow.SetShadowColour(wx.Colour(128, 128, 128))
self.SpeedWindow.SetSpeedValue(0.0)
# These Are Cosmetics For our SpeedMeter Control
# Create The Timer For The Clock
self.timer = wx.PyTimer(self.ClockTimer)
self.currvalue = 0
bsizer2 = wx.BoxSizer(wx.VERTICAL)
hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
stattext2 = wx.StaticText(panel, -1, "A Simple Clock", style=wx.ALIGN_CENTER)
button2 = wx.Button(panel, -1, "Stop")
self.stopped = 0
button2.Bind(wx.EVT_BUTTON, self.OnStopClock)
button2.SetToolTip(wx.ToolTip("Click To Stop/Resume The Clock"))
hsizer2.Add(button2, 0, wx.LEFT, 5)
#hsizer2.Add(stattext2, 1, wx.EXPAND)
#hsizer2.Add(self.helpbuttons[1], 0, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT, 5)
bsizer2.Add(self.SpeedWindow, 1, wx.EXPAND)
bsizer2.Add(hsizer2, 0, wx.EXPAND)
panel.SetSizer(bsizer2)
self.timer.Start(1000)
def ClockTimer(self):
if self.currvalue >= 59:
self.currvalue = 0
else:
self.currvalue = self.currvalue + 1
self.SpeedWindow.SetMiddleText(str(self.currvalue) + " s")
self.SpeedWindow.SetSpeedValue(self.currvalue/5.0)
def OnStopClock(self, event):
btn = event.GetEventObject()
if self.stopped == 0:
self.stopped = 1
self.timer.Stop()
btn.SetLabel("Resume")
else:
self.stopped = 0
self.timer.Start()
btn.SetLabel("Stop")
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
#frame.Maximize()
app.MainLoop()
Recently I moved from Debian to Mac OS X (Yosemite), and after starting my application getting error in terminal while running:
relrin at MacBook-Relrin in ~/code/Helenae/Helenae/helenae/gui on git:dev+? workon code
=> run_wx.sh CloudStorage.py
Traceback (most recent call last):
File "/Users/savicvalera/code/Helenae/Helenae/helenae/gui/widgets/Filemanager.py", line 286, in OnSize
self.sb.SetStatusText(os.getcwd())
File "/Users/savicvalera/code/Helenae/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 16711, in __getattr__
raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the StatusBar object has been deleted, attribute access no longer allowed.
However in Debian this application didn't say about any errors. How can I fix this issue?
Code:
# -*- coding: utf-8 -*-
import os
import wx
import shutil
import ntpath
from FileListCtrl import FileListCtrl
from OptionsCtrl import OptionsCtrl
from InputDialogCtrl import InputDialog
from validators.FolderValidator import FolderValidator
from validators.FileValidator import FileValidator
from validators.ValidatorMsgDlg import ValidatorMsgDialog as MsgDlg
ID_BUTTON = 100
ID_BUTTON_WRITE = 101
ID_BUTTON_TRANSFER = 102
ID_BUTTON_CREATE_FOLDER = 103
ID_BUTTON_REMOVE_FILE = 104
ID_BUTTON_RENAME = 105
ID_NEW = 150
ID_FOLDER = 151
ID_RENAME = 152
ID_REPLACE = 153
ID_REMOVE = 154
ID_SHOW_STATUSBAR = 155
ID_OPTIONS = 156
ID_WRITE = 157
ID_COPY_FILE = 158
ID_COPY_FOLDER = 159
ID_EXIT = 200
ID_SPLITTER = 300
ID_TOOLBAR_UPDIR = 201
ID_TOOLBAR_HOME = 202
ID_TOOLBAR_REFRESH = 203
ID_TOOLBAR_HELP = 204
class FileManager(wx.Frame):
def __init__(self, parent, id, title, ico_folder):
wx.Frame.__init__(self, parent, -1, title)
self.parent = parent
self.ico_folder = ico_folder
wx.Log.SetLogLevel(0)
# file frame
self.files_folder = FileListCtrl(self, -1, ico_folder)
# options frame
self.options_frame = OptionsCtrl(self, -1, "Опции", ico_folder)
# menu
filemenu= wx.Menu()
newItem = wx.MenuItem(filemenu, ID_NEW, "&Новый файл", help='Создать новый файл в каталоге')
newItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/new.png'))
createItem = wx.MenuItem(filemenu, ID_FOLDER, "&Создать каталог", help='Создать новый каталог')
createItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/folder.png'))
copyFileItem = wx.MenuItem(filemenu, ID_COPY_FILE, "&Скопировать файл", help='Скопировать файл извне в текущий каталог')
copyFileItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/copy_file.png'))
copyFolderItem = wx.MenuItem(filemenu, ID_COPY_FOLDER, "&Скопировать каталог", help='Скопировать каталог извне в текущий каталог')
copyFolderItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/copy_folder.png'))
renameItem = wx.MenuItem(filemenu, ID_RENAME, "&Перемеиновать", help='Перемеиновать выделенный файл')
renameItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/rename.png'))
removeItem = wx.MenuItem(filemenu, ID_REPLACE, "&Перенос", help='Перенести выделенные файлы в другой каталог')
removeItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/remove.png'))
writeItem = wx.MenuItem(filemenu, ID_WRITE, "&Запись", help='Записать выделенные файлы')
writeItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/write.png'))
deleteItem = wx.MenuItem(filemenu, ID_REMOVE, "&Удалить", help='Удалить выделенные файлы')
deleteItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/delete.png'))
filemenu.AppendItem(newItem)
filemenu.AppendItem(createItem)
filemenu.AppendSeparator()
filemenu.AppendItem(copyFileItem)
filemenu.AppendItem(copyFolderItem)
filemenu.AppendSeparator()
filemenu.AppendItem(renameItem)
filemenu.AppendItem(removeItem)
filemenu.AppendItem(writeItem)
filemenu.AppendItem(deleteItem)
filemenu.AppendSeparator()
exitItem = wx.MenuItem(filemenu, ID_EXIT, "&Выход", help='Выход из приложения')
exitItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/file/exit.png'))
filemenu.AppendItem(exitItem)
configmenu = wx.Menu()
self.show_statusbar = configmenu.Append(ID_SHOW_STATUSBAR, 'Отображать строку статуса', 'Отображать строку статуса', kind=wx.ITEM_CHECK)
configmenu.Check(self.show_statusbar.GetId(), True)
self.preferencesItem = wx.MenuItem(filemenu, ID_OPTIONS, "&Параметры", help='Основные параметры приложения')
self.preferencesItem.SetBitmap(wx.Bitmap(ico_folder + '/icons/ui/menu/preferences/preferences.png'))
configmenu.AppendItem(self.preferencesItem)
about = wx.Menu()
helpmenu = wx.Menu()
menuBar = wx.MenuBar()
menuBar.Append(filemenu, "&Файл")
menuBar.Append(configmenu, "&Настройки")
menuBar.Append(helpmenu, "&Помощь")
menuBar.Append(about, "&О программе")
self.SetMenuBar(menuBar)
# toolbar
tb = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT | wx.TB_TEXT)
tb.AddSimpleTool(ID_TOOLBAR_UPDIR, wx.Bitmap(ico_folder + '/icons/ui/toolbar/up.png'), 'Up one directory')
tb.AddSimpleTool(ID_TOOLBAR_HOME, wx.Bitmap(ico_folder + '/icons/ui/toolbar/home.png'), 'Home')
tb.AddSimpleTool(ID_TOOLBAR_REFRESH, wx.Bitmap(ico_folder + '/icons/ui/toolbar/refresh.png'), 'Refresh')
tb.AddSeparator()
tb.AddSimpleTool(ID_TOOLBAR_HELP, wx.Bitmap(ico_folder + '/icons/ui/toolbar/help.png'), 'Help')
tb.Realize()
# button panel
self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
button1 = wx.Button(self, ID_BUTTON_WRITE, "F5 Запись")
button1.SetBackgroundColour('#BFD8DF')
button1.SetForegroundColour("#2F4D57")
button2 = wx.Button(self, ID_BUTTON_TRANSFER, "F6 Перенос")
button2.SetBackgroundColour('#BFD8DF')
button2.SetForegroundColour("#2F4D57")
button3 = wx.Button(self, ID_BUTTON_CREATE_FOLDER, "F7 Созд. каталог")
button3.SetBackgroundColour('#BFD8DF')
button3.SetForegroundColour("#2F4D57")
button4 = wx.Button(self, ID_BUTTON_REMOVE_FILE, "F8 Удалить")
button4.SetBackgroundColour('#BFD8DF')
button4.SetForegroundColour("#2F4D57")
button5 = wx.Button(self, ID_BUTTON_RENAME, "F9 Перемеиновать")
button5.SetBackgroundColour('#BFD8DF')
button5.SetForegroundColour("#2F4D57")
button6 = wx.Button(self, ID_EXIT, "F10 Выход")
button6.SetBackgroundColour('#BFD8DF')
button6.SetForegroundColour("#2F4D57")
self.sizer2.Add(button1, 1, wx.EXPAND)
self.sizer2.Add(button2, 1, wx.EXPAND)
self.sizer2.Add(button3, 1, wx.EXPAND)
self.sizer2.Add(button4, 1, wx.EXPAND)
self.sizer2.Add(button5, 1, wx.EXPAND)
self.sizer2.Add(button6, 1, wx.EXPAND)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.files_folder, 1,wx.EXPAND)
self.sizer.Add(self.sizer2, 0,wx.EXPAND)
self.SetSizer(self.sizer)
# events bindings
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_MENU, self.ToggleStatusBar, self.show_statusbar)
self.Bind(wx.EVT_MENU, self.ShowMenu, self.preferencesItem)
self.Bind(wx.EVT_CLOSE, self.OnExitProgramm)
# create folder
self.Bind(wx.EVT_BUTTON, self.OnCreateFolder, id=ID_BUTTON_CREATE_FOLDER)
self.Bind(wx.EVT_MENU, self.OnCreateFolder, id=ID_FOLDER)
# create file
self.Bind(wx.EVT_MENU, self.OnCreateFile, id=ID_NEW)
# toolbar events
self.Bind(wx.EVT_TOOL, self.UpDir, id=ID_TOOLBAR_UPDIR)
self.Bind(wx.EVT_TOOL, self.Home, id=ID_TOOLBAR_HOME)
self.Bind(wx.EVT_TOOL, self.RefreshFileCtrl, id=ID_TOOLBAR_REFRESH)
# copy file
self.Bind(wx.EVT_MENU, self.CopyFile, id=ID_COPY_FILE)
# copy folder
self.Bind(wx.EVT_MENU, self.CopyFolder, id=ID_COPY_FOLDER)
# define size and icon for app
size = (800, 600)
self.SetSize(size)
self.icon = wx.Icon(ico_folder + '/icons/app.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(self.icon)
self.SetMinSize(size)
self.Center()
def UpDir(self, event):
if self.files_folder.currentDir != self.files_folder.defaultDir:
self.files_folder.currentDir = self.files_folder.getParentDir(self.files_folder.currentDir)
filepath = self.files_folder.currentDir
self.files_folder.showFilesInDirectory(filepath)
def Home(self, event):
self.files_folder.currentDir = self.files_folder.defaultDir
self.files_folder.showFilesInDirectory(self.files_folder.defaultDir)
def RefreshFileCtrl(self, event):
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
def OnCreateFolder(self, event):
dlg = InputDialog(self, -1, 'Введите каталог', self.ico_folder, FolderValidator())
dlg.ShowModal()
if dlg.result is not None:
try:
new_folder = self.files_folder.currentDir + dlg.result
os.makedirs(new_folder)
except OSError:
wx.MessageBox("Вероятнее всего, такой файл или каталог уже существует!\nПожалуйста, дайте файлу другое имя.", 'Ошибка')
except Exception, exc:
wx.MessageBox("%s" % exc.message, "Ошибка")
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
dlg.Destroy()
def OnCreateFile(self, event):
dlg = InputDialog(self, -1, 'Введите имя файла и расширение', self.ico_folder, FileValidator())
dlg.ShowModal()
if dlg.result is not None:
try:
new_file = self.files_folder.currentDir + dlg.result
new_folders, filename = ntpath.split(dlg.result)
if len(new_folders) > 2:
os.makedirs(self.files_folder.currentDir + new_folders)
open(new_file, 'a').close()
except OSError:
wx.MessageBox("Вероятнее всего, такой файл или каталог уже существует!\nПожалуйста, дайте файлу другое имя.", 'Ошибка')
except Exception, exc:
wx.MessageBox("%s" % exc.message, "Ошибка")
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
dlg.Destroy()
def CopyFile(self, event):
dlg = wx.FileDialog(self, "Укажите путь к файлу", "", "", "All files (*.*)|*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dlg.ShowModal() == wx.ID_OK:
filepath = dlg.GetPath()
dir, filename = ntpath.split(filepath)
shutil.copyfile(filepath, self.files_folder.currentDir+filename)
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
msg_dlg = MsgDlg(None, "Копирование завершено!")
msg_dlg.ShowModal()
dlg.Destroy()
def CopyMoveOperation(self, src, target, operation='copy'):
for src_dir, dirs, files in os.walk(src):
dst_dir = src_dir.replace(src, target)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
if operation is 'copy':
shutil.copy(src_file, dst_dir)
elif operation is 'move':
shutil.move(src_file, dst_dir)
def CopyFolder(self, event):
dlg = wx.DirDialog(self, "Укажите директорию", style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
folderpath = dlg.GetPath()
try:
new_folder = folderpath.split('/')[-1]
os.mkdir(new_folder)
# if this folder already exists - then catch exception, ignore him, and copy files right now
except OSError:
pass
self.CopyMoveOperation(folderpath, self.files_folder.currentDir+new_folder)
self.files_folder.showFilesInDirectory(self.files_folder.currentDir)
msg_dlg = MsgDlg(None, "Копирование завершено!")
msg_dlg.ShowModal()
dlg.Destroy()
def ShowMenu(self, event):
self.options_frame.Show()
def ToggleStatusBar(self, event):
if self.show_statusbar.IsChecked():
self.sb.Show()
else:
self.sb.Hide()
def OnExit(self, event):
self.Close()
def OnExitProgramm(self, event):
self.parent.Close()
def OnSize(self, event):
size = self.GetSize()
self.files_folder.ResizeColumns(size.x)
if not hasattr(self, 'sb'):
self.sb = self.CreateStatusBar()
self.sb.SetStatusText(os.getcwd())
event.Skip()
if __name__ == '__main__':
app = wx.App(0)
ico_folder = '..'
frame = FileManager(None, -1, 'CloudStorage', ico_folder)
frame.Show(True)
app.MainLoop()
You can capture the error in a try exception block with a wx.PyDeadObjectError exception.
You can also remove the hasattr by using a AttributeError exception.
def OnSize(self, event):
size = self.GetSize()
self.files_folder.ResizeColumns(size.x)
cwd = os.getcwd()
try:
self.sb.SetStatusText(cwd)
except AttributeError:
self.sb = self.CreateStatusBar()
self.sb.SetStatusText(cwd)
except wx.PyDeadObjectError:
pass
event.Skip()
I have a window contains different kinds of controls.
class FindReplaceWindow(wx.MiniFrame):
def __init__(self, parent):
Style = wx.DEFAULT_MINIFRAME_STYLE|wx.SYSTEM_MENU|wx.CLOSE_BOX
super(FindReplaceWindow, self).__init__(parent, -1, 'Find and Replace', style = Style)
self.BackgroundColour = wx.WHITE
self.MaxSize = wx.Size(400,300)
self.MinSize = self.MaxSize
self.CenterOnParent()
self.LabelFind = wx.StaticText(self, label = 'Find')
self.LabelReplace = wx.StaticText(self, label = 'Replace')
self.LabelTransparency = wx.StaticText(self, label = 'Transparency')
self.TextFind = wx.TextCtrl(self, size = (350,20), style = wx.TE_PROCESS_TAB)
self.TextReplace = wx.TextCtrl(self, size = (350,20), style = wx.TE_PROCESS_TAB)
self.SearchDirection = wx.RadioBox(self, -1, 'Search Direction',
size = (110,-1), choices = ('Up','Down'), style = wx.RA_VERTICAL)
self.SearchMode = wx.RadioBox(self, -1, 'Search Mode',
size = (110, -1), choices = ('Text','Regex'), style = wx.RA_VERTICAL)
self.Flags = wx.CheckListBox(self, -1, wx.DefaultPosition,
(95,-1), ('Ignore Case','Whole Word(s)','Selection Only'), wx.VERTICAL)
self.ButtonFind = wx.Button(self, wx.ID_FIND, 'Find')
self.ButtonReplace = wx.Button(self, wx.ID_REPLACE, 'Replace')
self.ButtonReplaceAll = wx.Button(self, wx.ID_REPLACE_ALL, 'Replace All')
How do I switch between them using Tab button?
Take a look at the wx.TAB_TRAVERSAL flag. There's some example code here (it also includes an alternate method): http://wiki.wxpython.org/Getting%20Started#How_to_get_tabs_to_work