I used PythonCard to make my GUI and the only menu items I have currently are Save and Exit. Exit is fully functional and closes the program; but when I click on Save nothing happens. I can only assume the command is wrong. I have done some thorough searching and have found nothing. The command I used was "save". Obviously this is not correct. Can anyone tell me what command I need to use?
Resource File
There's really not enough information here. You need to bind EVT_MENU to an event handler for the save menu item. Then in the event handler, you'll have to define what the "Save" behavior is. For example, does it save to a database, a file, or what? Once you have that figured out, you put it in your handler and do it or have the handler spin up a thread.
EDIT: If you want to save a file, see the wx.FileDialog and set the style flag to wx.SAVE. Something like this should work:
def onSaveFile(self, event):
"""
Create and show the Save FileDialog
"""
wildcard = "Text (*.txt)|*.txt|" \
"All files (*.*)|*.*"
dlg = wx.FileDialog(
self, message="Save file as ...",
defaultDir=self.currentDirectory,
defaultFile="", wildcard=wildcard, style=wx.SAVE
)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
print "You chose the following filename: %s" % path
dlg.Destroy()
See also the wxPython demo, or this or the docs
Related
I'm running a script coded in python from a scripts menu in a desktop application. It's basically a giant macro that I wrote and added a GUI to. I'm pretty sure the GUI is a really old one that my desktop app uses called dialogKit from MIT.
GitHub still has it here.
The problem is the word "stop" at the very end of the dialog code.
I keep getting a "stop is undefined" message, which I understand, but I've tried everything to close the dialog and if I use exit(), sys.exit(), I don't get an error, but it also closes my entire desktop app.
I need to close the dialog and keep the software open.
The limited dialog documentation for what I'm using can be found here.
(you might have to click on the Dialog section. Their site uses frames.)
class MyDialog:
def __init__(self):
self.d = Dialog(self)
self.d.size = Point(300, 340)
self.d.Center()
self.d.title = "Halftone" #<----- Title of the dialogue
self.d.AddControl(STATICCONTROL, Rect(aIDENT, aIDENT, aIDENT, aIDENT), "frame", STYLE_FRAME)
# more controls and methods..
def on_ok(self, code):
return 1
def on_cancel(self, code):
print "blah"
def Run(self):
return self.d.Run()
d = MyDialog()
if d.Run()!= 1:
stop
I just need a way to change stop to something that 1) will prevent the script from running, and 2) close the dialog without quitting the entire application. This is the functionality of a typical "cancel" button, which is what I want.
Another option is the method called on_cancel(), which I also tried and could get the event itself to work, but still the entire application quits with any kind of exit().
The docs show a method called End(), which claims to terminate the dialog object, but I've tried and failed to get that to work either.
Okay, I'm posting an answer because I think I have a handle on your problem.
Try replacing stop with:
d.d.End()
If that works, you might want to try putting:
self.d.End()
inside of the on_cancel function in your class. That should close the dialogue without closing your program.
Python 2.7.3 x64
wxPython 2.8 x64
I'm having trouble changing the font of the wxpython message dialog box. I'd like to use a fixed-width font (I think wxFAMILY_MODERN is) to control the formatting of the output. Here's the code I'm using to test with ...
def infDialog (self, msg, title):
""" Display Info Dialog Message """
font = wx.Font(14, wx.MODERN, wx.NORMAL, wx.NORMAL)
style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP
dialog = wx.MessageDialog(self, msg, title, style)
dialog.CenterOnParent()
dialog.SetFont(font)
result = dialog.ShowModal()
if result == wx.ID_OK:
print dialog.GetFont().GetFaceName()
dialog.Destroy()
return
# End infDialog()
But the results when I click OK are always "Arial". Any thoughts? Perhaps I need to make a custom dialog class?
Thanks,
-RMWChaos
The wx.MessageDialog is a wrapper around the OS / system message dialog. I suspect each OS only allows so much editing or none at all. So yes, using a custom wx.Dialog or the generic message dialog widget (wx.lib.agw.genericmessagedialog) is the way to go if fonts are important.
I was looking all over the internet and found that no one actually took the time to answer the question, instead just telling users to create their own dialog class. There is actually an easy way in which you should be able to change the font of your message dialog. Grabbing the dialog's textCtrl object and then setting the font of that object should do the trick.
Simply replace:
dialog.SetFont(font)
with
txt_ctrl = dialog.text
txt_ctrl.SetFont(font)
Let me know if this works for you.
What I'm trying to do here is select multiple files from within a wxPython frame app and then utilize those file paths within another function within the same wxPython app. I realize I can use the following code to select multiple files:
def OnOpen(self,e)
dialog = wx.FileDialog(self, "Choose a file", "", "", "*.", wx.MULTIPLE)
if dialog.ShowModal() == wx.ID_OK:
filelist = dialog.GetPaths()
So the 'filelist' variable is now a list of the files the user selects. However, I can't seem to find a way to utilize this list in another function. I was hoping I could just use a return statement within this function in another function and assign it to a variable, but it doesn't seem to allow me to do this. I guess this is because I have a button event already using this function. Any help on this would be greatly appreciated.
I don't think I fully understand the issue here. The OnOpen function is an event handler for a button click? So it is executed when button is clicked. A windowed application (like yours using wxPython) is usually event driven, it responds to events like a button click. The main GUI thread loops and analyses events which can be handled by you application. So when you write an application these event handlers are entry points for actions you would like to perform.
I think the best way to do is simply the other function and pass filelist in parameter e.g:
def OnOpen(self,e)
dialog = wx.FileDialog(self, "Choose a file", "", "", "*.", wx.MULTIPLE)
if dialog.ShowModal() == wx.ID_OK:
filelist = dialog.GetPaths()
self.otherFunc(filelist)
def otherFunc(self, filelist):
"do something here"
saving filelist to an attribute may be problematic sometimes. As I said you may have multiple entry points which would like to use filelist attribute, you have to predict possible problems. But as I said at the beginning - I might have not fully understood your problem.
Another possiblity: maybe your problem is that you would like to actually reuse OnOpen? First possibility is to pass None as an argument because e is not used. Another, better possibility is to define OnOpen without e argument and change the event binding to self.Bind(wx.EVT_BUTTON, self.OnButtonwx.EVT_BUTTON(<some object>, lambda evt: self.OnOpen()). You explicitly say here that you don't need the evt argument.
Put the list as an attribute in self, or have self contain as an attribute a listener that gets the paths, or call the other function giving it the paths as an argument?
Hey guys I've been trying to debug this issue for a while to no avail.
I've defined a function bound to a button that calls up a FileDialog, if the user clicks OK, the function resumes. Immediately after ID_OK I attempted to call a simple dialog prompting the user to select files from another directory. Immediately after this message dialog appears, there appears to be a delay where the user can't press OK or CANCEL on the first click. It takes repeated clicking for the buttons to respond. If anybody has any idea what's going on here or what can be done to debug this issue I will be very grateful :). I've attached the snippet of code (albeit with a SingleChoiceDialog though the behavior is the same as with MessageDialog). For the record dlg is destroyed after the conditional statement.
def openFile(self, event):
import os
import re
import csv
import sets
import datetime
dlg = wx.FileDialog(self, "Choose file(s)", os.getcwd(), "", "*.*", wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPaths()
test = wx.SingleChoiceDialog(self, 'Add more files from different directories?', 'Selected Files', path, style=wx.CHOICEDLG_STYLE)
while test.ShowModal() == wx.ID_OK:
dlgAdd = wx.FileDialog(self, "Choose file(s)", os.getcwd(), "", "*.*", wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
if dlgAdd.ShowModal() == wx.ID_CANCEL:
break
dlgAdd.Destroy()
path = path + dlgAdd.GetPaths()
test = wx.SingleChoiceDialog(self, 'Add more files from different directories?', 'Selected Files', path, style=wx.CHOICEDLG_STYLE)
test.Destroy()
Was digging around some more online and found reports of similar issues: http://comments.gmane.org/gmane.comp.python.wxpython/55470. It does seem to be an issue with passing focus though none of them offered fixes or workarounds however.
Try using an "if" instead of a "while" for the "test" dialog. I suspect you have an infinite or near-infinite loop thing going on whenever they press the OK button. If the user presses CANCEL on the dlgAdd dialog, your program never destroys dlgAdd since it breaks out of the loop at that point. That's also an issue and probably why the "test" dialog is hung for a while.
Ugh okay figured it out the error stems from the use of Coherence mode when using Parallels. After turning this off the dialogs worked perfectly.
I have created different shapes like circle/rect etc in my program using BufferedPaintDC on event. Now i want to save the file as I click the saveas button in the menu option. For that I am using memoryDC and save the contents as bmp file.
def Saveas(self,event):
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", \
wx.SAVE | wx.OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK: # user enters filename as something.bmp
self.show_bmp = wx.StaticBitmap(self)
w, h = self.GetClientSize()
draw_bmp = wx.EmptyBitmap(w, h)
c = wx.MemoryDC(draw_bmp)
c.SetBrush(wx.Brush('white'))
c.Clear()
c.SetPen(wx.Pen("purple", 15))
c.DrawRectangle(30,30,60,60) ### ??????####
myimage = self.show_bmp.GetBitmap()
self.filename=dlg.GetFilename()
name = os.path.join('C:\mad', self.filename)
myimage.SaveFile(name, wx.BITMAP_TYPE_JPEG)
self.filename=name
dlg.Destroy()
Now my problem is how do I get the things drawn by the buffered dc on the " c ", so that they can be then converted to image?? I hope my question is clear.As u can see I am drawing the rectangle on the "c" and that is being converted to an image. But I want to get the shapes created on ONPaint . How do I extract that?
Thanks
What you're asking is very close to saying you want to take a screenshot. Although technically grabbing a copy of what the window currently looks like is not the same as cloning what the OnPaint does, it's possible it would do the job for you.
If it doesn't work, take note of the technique, including the use of DC.Blit(), as those would be the tools you'd use.
See this wxpython-users mailing list post by Andrea Gavana for image-grabbing code.
Edit: if the problem is that because you're doing all your drawing inside the EVT_PAINT handler, then you probably need a different technique. Draw everything from a different routine to a pre-allocated buffer bitmap. Inside the OnPaint, which is just how the image actually gets to the screen, you don't draw, you just copy the already-drawn bitmap. The buffer bitmap persists between OnPaint calls (and in fact is basically independent of OnPaint), so you can add a Save() routine that works rather simply as well. See the wxPyWiki DoubleBuffererDrawing page for various snippets that will show you how to do that. (Also note, this will be a bit of a learning curve, so ask for more help if it's not enough.)