Python PBI.PyBusyInfo stays on top - python

I have the code below which opens Quicktime via applescript and does stuff to files, which take a little while and mustn't be disturbed. I want a dialog window to open on top of everything else, not matter what it must stay on top, which just says "Processing files, please wait". This code works, but as soon as quicktime opens via applescript the PBI.PyBusyInfo disappears. Any idea how I could do this please?
import wx
import os
import os.path
import wx.lib.agw.pybusyinfo as PBI
from subprocess import Popen, PIPE
class ScrolledWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(510, 370), style=wx.STAY_ON_TOP | wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
wx.RESIZE_BOX |
wx.MAXIMIZE_BOX))
self.tabbed = wx.Notebook(self, -1, style=(wx.NB_TOP))
run_params = {}
run_params["dropList1"] = ['HD 1920x1080', 'PAL 4x3', 'PAL 16x9', 'NTSC 4x3', 'NTSC 16x9']
run_params["dropList2"] = ['Progressive', 'Interlaced']
self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
self.SetMenuBar(menuBar)
panel = wx.Panel(self, -1)
self.Centre()
self.Show()
self.filePrep = PrepFile(self.tabbed, run_params)
self.tabbed.AddPage(self.filePrep, "File Prep")
class PrepFile(wx.Panel):
def __init__(self, parent, run_params):
wx.Panel.__init__(self, parent)
self.run_params = run_params
self.fieldChoice = 'Progressive'
self.formatOption = 'HD 1920x1080'
outputOption = '''Format'''
wx.StaticText(self, -1, outputOption, (33, 22), style=wx.ALIGN_CENTRE)
self.choice1 = wx.Choice(self, pos=(35, 40), choices=self.run_params["dropList1"])
self.choice1.SetSelection(0)
self.choice1.SetFocus()
self.choice1.Bind(wx.EVT_CHOICE, self.selectOption)
fieldSetText = '''Fields'''
wx.StaticText(self, -1, fieldSetText, (33, 82), style=wx.ALIGN_CENTRE)
self.choice2 = wx.Choice(self, pos=(35, 100), choices=self.run_params["dropList2"])
self.choice2.SetSelection(0)
self.choice2.SetFocus()
self.choice2.Bind(wx.EVT_CHOICE, self.fieldSet)
self.buttonClose = wx.Button(self, -1, "Quit", pos=(195, 250))
self.buttonClose.Bind(wx.EVT_BUTTON, self.OnClose)
greyBox = wx.StaticBox(self, -1, '', pos=(20, 15), size=(235, 130))
outputtxt3 = '''Drag and Drop Quicktimes'''
wx.StaticText(self, -1, outputtxt3, pos=(35, 170), style=wx.ALIGN_CENTRE)
self.drop_target = MyFileDropTarget(self)
self.SetDropTarget(self.drop_target)
self.tc_files = wx.TextCtrl(self, wx.ID_ANY, pos=(38, 190), size=(200, 25))
self.buttonSubmit = wx.Button(self, -1, "Submit", pos=(250,190))
self.buttonSubmit.Bind(wx.EVT_BUTTON, self.submit)
def EvtRadioBox(self, event):
self.mode = (event.GetString())
def selectOption(self, e):
self.formatOption = self.choice1.GetStringSelection()
def fieldSet(self, e):
self.fieldChoice = self.choice2.GetStringSelection()
def setSubmissionDrop(self, dropFiles):
"""Called by the FileDropTarget when files are dropped"""
self.tc_files.SetValue(','.join(dropFiles))
self.selectedFiles = dropFiles
print self.selectedFiles
def submit(self, event):
event.Skip()
message = "Please wait..."
busy = PBI.PyBusyInfo(message, parent=self, title="Processing Files")
wx.Yield()
for item in self.selectedFiles:
if os.path.isdir(item):
print "It is a folder!"
for root, dirs, files in os.walk(item):
for file1 in files:
if file1.endswith(".mov"):
currentFile = os.path.join(root, file1)
self.jesFile(currentFile)
print "Finished"
del busy
def doSomething(self):
print "Open Quicktime and process files via applescript"
def OnClose(self, e):
CloseApp()
class MyFileDropTarget(wx.FileDropTarget):
""""""
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
self.window.setSubmissionDrop(filenames)
app = wx.App()
ScrolledWindow(None, -1, 'App')
app.MainLoop()

Your question seems to be missing the call where you start the AppleScript (it looks like you forgot to add the jesFile method to your example code). I can only speculate so much on your code that isn't in the posted example... but my guess is your call to do processing isn't a blocking call, so you either need to make it a blocking call, or save busy to a class variable that you delete when the non-blocking process call returns (hopefully you can bind a callback function for when that happens).

Related

wxPython Drag and Drop files onto image, to add to array

I have a simple wxPython application with 1 image "Drop files here!" and 2 buttons.
I want the user to be able to drag and drop files onto the top section/image, at which point the image changes and the files are loaded into an array.
That's all I need but I have hit a major roadblock getting the drag and drop to work. Can someone please take a look at my code and figure out how/where to integrate the Drag and drop event? Any help would be great.
UI image
import wx
class DropTarget(wx.FileDropTarget):
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
def __init__(self, parent, ID, title):
wx.FileDropTarget.__init__(self, parent, ID, title, size=(300, 340), style= wx.CLOSE_BOX)
#self.widget = widget
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title, size=(300, 340), style= wx.CLOSE_BOX)
panel1 = wx.Panel(self,-1, style=wx.SUNKEN_BORDER)
panel2 = wx.Panel(self,-1, style=wx.SUNKEN_BORDER)
panel1.SetBackgroundColour("BLUE")
panel2.SetBackgroundColour("RED")
image_file = 'bgimage1.png'
bmp1 = wx.Image(
image_file,
wx.BITMAP_TYPE_ANY).ConvertToBitmap()
# image's upper left corner anchors at panel
# coordinates (0, 0)
self.bitmap1 = wx.StaticBitmap(
self, -1, bmp1, (0, 0))
# show some image details
str1 = "%s %dx%d" % (image_file, bmp1.GetWidth(),
bmp1.GetHeight())
# button
closeButton = wx.Button(self.bitmap1, label='Generate', pos=(30, 280))
closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
clearButton = wx.Button(self.bitmap1, label='Clear', pos=(170, 280))
clearButton.Bind(wx.EVT_BUTTON, self.OnClose)
box = wx.BoxSizer(wx.VERTICAL)
box.Add(panel1, 5, wx.EXPAND)
box.Add(panel2, 1, wx.EXPAND)
self.SetAutoLayout(True)
self.SetSizer(box)
self.Layout()
def OnDropFiles(self, x, y, filenames):
self.window.updateDisplay(filenames)
for name in filenames:
self.window.WriteText(name + "\n")
print(name)
return True
def OnClose(self, e):
self.Close(True)
app = wx.App()
frame = MyFrame(None, -1, "Sizer Test")
frame.Show()
app.MainLoop()
You have the class DropTarget back to front with the init after the dropfiles. You also need to put the image and buttons on to one of the panels.
See below:
import wx
class DropTarget(wx.FileDropTarget):
def __init__(self, obj):
wx.FileDropTarget.__init__(self)
self.obj = obj
def OnDropFiles(self, x, y, filenames):
print("Drop Event",filenames)
# image = Image.open(filenames[0])
# image.thumbnail((PhotoMaxSize, PhotoMaxSize))
# image.save('new.png')
# pub.sendMessage('dnd', filepath='new.png')
return True
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title, size=(300, 340))
panel1 = wx.Panel(self,-1, style=wx.SUNKEN_BORDER)
panel2 = wx.Panel(self,-1, style=wx.SUNKEN_BORDER)
panel1.SetBackgroundColour("BLUE")
panel2.SetBackgroundColour("RED")
image_file = 'bgimage1.png'
bmp1 = wx.Image(image_file,wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.bitmap1 = wx.StaticBitmap(panel1, -1, bmp1, (0, 0))
# button
closeButton = wx.Button(panel2, -1, label='Generate',pos=(30, 280))
closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
clearButton = wx.Button(panel2, -1, label='Clear',pos=(170, 280))
clearButton.Bind(wx.EVT_BUTTON, self.OnClose)
self.file_drop_target = DropTarget(self)
self.SetDropTarget(self.file_drop_target)
box = wx.BoxSizer(wx.VERTICAL)
box.Add(panel1, 0, wx.EXPAND,0)
box.Add(panel2, 0, wx.EXPAND,0)
self.SetAutoLayout(True)
self.SetSizer(box)
self.Layout()
def OnClose(self, e):
self.Close(True)
app = wx.App()
frame = MyFrame(None, -1, "Sizer Test")
frame.Show()
app.MainLoop()
This may not be what you want to achieve but at least it's a startiing point and the drag and drop works.

How can I put another 3 buttons on this WXPython programs

I'm new programming in WXPython and I Took this program from internet to start programming a visual program.
But How can I put 3 more buttons on this program without having errors?
import wx
class Panel1(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
try:
image_file = "roses.jpg"
bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.bitmap1 = wx.StaticBitmap(self, -1, bmp1, (0, 0))
def InitUI(self):
str1 = "%s %dx%d" % (image_file, bmp1.GetWidth(), bmp1.GetHeight())
parent.SetTitle(str1)
except IOError:
print "Image file %s not found" % imageFile
raise SystemExit
self.button1 = wx.Button(self.bitmap1, id=-1, label='Snake', pos=(200, 300))
app = wx.PySimpleApp()
frame1 = wx.Frame(None, -1, "An image on a panel", size=(640, 480))
panel1 = Panel1(frame1, -1)
frame1.Show(True)
app.MainLoop()
I tried this code and it doesn't work for me. It gives me error "Segmentation faul"
Using self.bitmap1 as a Button's parent seems strange for me so I tried to use self (Panel1) as a parent and it works for me.
I made some other modifications - I added self. to some variables, I added self.parent. I moved InitUI
#!/usr/bin/env python
import wx
class Panel1(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.parent = parent
try:
self.image_file = "roses.jpg"
self.bmp1 = wx.Image(self.image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.bitmap1 = wx.StaticBitmap(self, -1, self.bmp1, (0, 0))
except IOError:
print "Image file %s not found" % self.image_file
raise SystemExit
self.InitUI()
self.button1 = wx.Button(self, id=-1, label='Snake', pos=(200, 300))
self.button2 = wx.Button(self, id=-1, label='Apple', pos=(100, 100))
def InitUI(self):
str1 = "%s %dx%d" % (self.image_file, self.bmp1.GetWidth(), self.bmp1.GetHeight())
self.parent.SetTitle(str1)
app = wx.PySimpleApp()
frame1 = wx.Frame(None, -1, "An image on a panel", size=(640, 480))
panel1 = Panel1(frame1, -1)
frame1.Show(True)
app.MainLoop()

TextCtrl doesn't work properly with CheckBox

I wrote a code to receive some input data from user using both CheckBox and TextCtrl. The problem is when I marked the checkbox and textctrl appears, it accept to receive input data, but won't replace with the default one!
import wx
class mainClass(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Interface', size=(500, 250))
self.panel = wx.Panel(self)
self.checkReplaceJob = wx.CheckBox(self.panel, -1, "Replace data", (35, 60), (235, 20))
self.Bind(wx.EVT_CHECKBOX, self.replaceJob, self.checkReplaceJob)
self.RunBut = wx.Button(self.panel, -1, "Run", pos=(150, 150))
self.Bind(wx.EVT_BUTTON, self.RunClick, self.RunBut)
self.RunBut.SetDefault()
self.CloseBut = wx.Button(self.panel, -1, "Close", pos=(250, 150))
self.Bind(wx.EVT_BUTTON, self.CloseClick, self.CloseBut)
def CloseClick(self, event):
self.Close()
def replaceJob(self, event):
if(self.checkReplaceJob.IsChecked()):
self.repJobRetName()
self.btn = wx.Button(self.panel, wx.ID_ANY, "&Help", pos=(345, 82))
self.Bind(wx.EVT_BUTTON, self.HelpJobName, self.btn)
def repJobRetName(self):
self.label = wx.StaticText(self.panel, -1, label = "New name:", pos=(165,87))
self.entry = wx.TextCtrl(self.panel, -1, value = u"Task-1", pos=(230, 84))
repJobName = self.entry.GetValue()
return repJobName
def HelpJobName(self, event):
help = 'Write out new name.'
wx.MessageBox(help, "Help")
def RunClick(self, event):
if(self.checkReplaceJob.IsChecked()):
replaceName = self.repJobRetName()
wx.MessageBox('The new name is: ' + replaceName, "Info")
#############=======================
if __name__ == "__main__":
app = wx.App(False)
mainClass().Show()
app.MainLoop()
Let me make sure I understand correctly. You want the text control to have a default value when it is created, but you want that value to disappear when you actually select the control. Is that correct? If so, then you just need to add a binding to wx.EVT_SET_FOCUS and do a little work when the widget gets focus. Here's an example:
import wx
class mainClass(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Interface', size=(500, 250))
self.panel = wx.Panel(self)
self.checkReplaceJob = wx.CheckBox(self.panel, -1, "Replace data", (35, 60), (235, 20))
self.Bind(wx.EVT_CHECKBOX, self.replaceJob, self.checkReplaceJob)
self.RunBut = wx.Button(self.panel, -1, "Run", pos=(150, 150))
self.Bind(wx.EVT_BUTTON, self.RunClick, self.RunBut)
self.RunBut.SetDefault()
self.CloseBut = wx.Button(self.panel, -1, "Close", pos=(250, 150))
self.Bind(wx.EVT_BUTTON, self.CloseClick, self.CloseBut)
def CloseClick(self, event):
self.Close()
def replaceJob(self, event):
if(self.checkReplaceJob.IsChecked()):
self.repJobRetName()
self.btn = wx.Button(self.panel, wx.ID_ANY, "&Help", pos=(345, 82))
self.Bind(wx.EVT_BUTTON, self.HelpJobName, self.btn)
def repJobRetName(self):
self.label = wx.StaticText(self.panel, -1, label = "New name:", pos=(165,87))
self.entry = wx.TextCtrl(self.panel, -1, value = u"Task-1", pos=(230, 84))
self.entry.Bind(wx.EVT_SET_FOCUS, self.onFocus)
repJobName = self.entry.GetValue()
return repJobName
def onFocus(self, event):
current_value = self.entry.GetValue()
if current_value == "Task-1":
self.entry.SetValue("")
def HelpJobName(self, event):
help = 'Write out new name.'
wx.MessageBox(help, "Help")
def RunClick(self, event):
if(self.checkReplaceJob.IsChecked()):
replaceName = self.repJobRetName()
wx.MessageBox('The new name is: ' + replaceName, "Info")
#############=======================
if __name__ == "__main__":
app = wx.App(False)
mainClass().Show()
app.MainLoop()

Threading not working

I am trying to get this little file copy application working which shows a progress bar, but I am not understanding why this won't work, as it locks up the gui whilst updating the gauge.
import shutil
import os
import threading
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
self.source = os.path.expanduser("~/Desktop/FolderToCopy")
self.destination = os.path.expanduser("~/Desktop/BackupFolder/Temp")
panel = wx.Panel(self, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
hbox4 = wx.BoxSizer(wx.HORIZONTAL)
self.getSourceSize = self.get_size(self.source)
self.gauge = wx.Gauge(panel, -1, self.getSourceSize, size=(150, 25))
self.btn1 = wx.Button(panel, wx.ID_OK)
self.abortButton = wx.Button(panel, label="Abort")
self.Bind(wx.EVT_BUTTON, self.OnButtonSelect, self.btn1)
self.abortButton.Bind(wx.EVT_BUTTON, self.OnAbortButton, self.abortButton)
hbox1.Add(self.gauge, 1, wx.ALIGN_CENTRE)
hbox2.Add(self.btn1, 1, wx.RIGHT, 10)
hbox4.Add(self.abortButton, 1, wx.RIGHT, 20)
vbox.Add((0, 50), 0)
vbox.Add(hbox1, 0, wx.ALIGN_CENTRE)
vbox.Add((0, 30), 0)
vbox.Add(hbox2, 1, wx.ALIGN_CENTRE)
vbox.Add(hbox4, 1, wx.ALIGN_CENTRE)
panel.SetSizer(vbox)
self.Centre()
def OnAbortButton(self, e):
self.shouldAbort = True
def get_size(self, start_path):
total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
total_size += os.path.getsize(fp)
total_size = total_size / 50
return total_size
def OnButtonSelect(self, event):
thread1 = threading.Thread(target=shutil.copytree, args=(self.source, self.destination))
thread1.start()
self.thread1 = threading.Thread(target=self.OnGo(self))
self.thread1.start()
def OnCopy(self):
shutil.copytree(self.source, self.destination)
def OnGo(self, event):
self.shouldAbort = False
getDestinationSize = 0
get_size = self.get_size
while getDestinationSize < self.getSourceSize:
getDestinationSize = get_size(self.destination)
self.gauge.SetValue(getDestinationSize)
if self.shouldAbort:
break
app = wx.App(0)
frame = MyFrame(None, -1, 'gauge.py')
frame.Show(True)
app.MainLoop()
self.thread1 = threading.Thread(target=self.OnGo(self))
self.thread1.start()
You're executing self.onGo on this line, before the thread even starts. Arguments to the target should be passed in via args. Since OnGo never actually uses its event parameter, you can just pass in None.
self.thread1 = threading.Thread(target=self.OnGo, args=(None,))
self.thread1.start()

Using wxPython to get input from user

Suppose I need to replace the raw_input function in the following code with a wxPython dialog box that asks for user input and returns the value to program:
...
x = raw_input("What's your name?")
print 'Your name was', x
...
I'm just looking for a simple way to do that.
Thanks
Here is another simple way that does what I was looking for:
import wx
def ask(parent=None, message='', default_value=''):
dlg = wx.TextEntryDialog(parent, message, defaultValue=default_value)
dlg.ShowModal()
result = dlg.GetValue()
dlg.Destroy()
return result
# Initialize wx App
app = wx.App()
app.MainLoop()
# Call Dialog
x = ask(message = 'What is your name?')
print 'Your name was', x
This is fairly trivial. Here is one way.
import wx
class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(-1, -1))
self.panel = wx.Panel(self)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
self.btn = wx.Button(self.panel, -1, "Name-a-matic")
self.Bind(wx.EVT_BUTTON, self.GetName, self.btn)
self.txt = wx.TextCtrl(self.panel, -1, size=(140,-1))
self.txt.SetValue('name goes here')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.btn)
sizer.Add(self.txt)
self.panel.SetSizer(sizer)
self.Show()
def GetName(self, e):
dlg = wx.TextEntryDialog(self.panel, 'Whats yo name?:',"name-o-rama","",
style=wx.OK)
dlg.ShowModal()
self.txt.SetValue(dlg.GetValue())
dlg.Destroy()
def OnCloseWindow(self, e):
self.Destroy()
app = wx.App()
frame = Frame(None, 'My Nameomatic')
app.MainLoop()
And here is another way:
import wx
class NameDialog(wx.Dialog):
def __init__(self, parent, id=-1, title="Enter Name!"):
wx.Dialog.__init__(self, parent, id, title, size=(-1, -1))
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
self.label = wx.StaticText(self, label="Enter Name:")
self.field = wx.TextCtrl(self, value="", size=(300, 20))
self.okbutton = wx.Button(self, label="OK", id=wx.ID_OK)
self.mainSizer.Add(self.label, 0, wx.ALL, 8 )
self.mainSizer.Add(self.field, 0, wx.ALL, 8 )
self.buttonSizer.Add(self.okbutton, 0, wx.ALL, 8 )
self.mainSizer.Add(self.buttonSizer, 0, wx.ALL, 0)
self.Bind(wx.EVT_BUTTON, self.onOK, id=wx.ID_OK)
self.Bind(wx.EVT_TEXT_ENTER, self.onOK)
self.SetSizer(self.mainSizer)
self.result = None
def onOK(self, event):
self.result = self.field.GetValue()
self.Destroy()
def onCancel(self, event):
self.result = None
self.Destroy()
class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(-1, -1))
self.panel = wx.Panel(self)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
self.btn = wx.Button(self.panel, -1, "Name-a-matic")
self.Bind(wx.EVT_BUTTON, self.GetName, self.btn)
self.txt = wx.TextCtrl(self.panel, -1, size=(140,-1))
self.txt.SetValue('name goes here')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.btn)
sizer.Add(self.txt)
self.panel.SetSizer(sizer)
self.Show()
def GetName(self, e):
dlg = NameDialog(self)
dlg.ShowModal()
self.txt.SetValue(dlg.result)
def OnCloseWindow(self, e):
self.Destroy()
app = wx.App()
frame = Frame(None, 'My Nameomatic')
app.MainLoop()

Categories

Resources