I am working on some software for the company that I work for. I am using wx for the GUI. I basically have this:
When the program is busy or loading, I create a wx.BusyInfo object. But, sometimes, while this busy info box is still visible, and I need to print an error message to the user, but that MessageDialog actually is popping up underneath the BusyInfo box. Why?
Is there a way to make the error show on top of the BusyInfo? I tried the wx.STAY_ON_TOP option, and it did not work.
I need it to work this way because, my classes are getting convoluted, and I don't want to have to delete the BusyInfo, show the error, then recreate the BusyInfo; it would be easier for my code, to just have the MessageDialog error show on top of the BusyInfo box.
Thanks.
Here is some sample code for what I am trying to do:
# myWindow is the main Window or Frame
wx.BusyInfo("Loading, please wait ...", myWindow)
wx.MessageDialog(myWindow, "Error message", "Error!", style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
After lots of google searches and research I found out how to solve the issue! First, instead of using wx.BusyInfo I use PyBusyInfo (I found the code here: https://searchcode.com/codesearch/view/63249201/). This is because, wx.BusyInfo is not actually inherited from a wx.Window class, but PyBusyInfo is; we need the busy's frame because we will pass it into wx.MessageDialog. Then, I just pass in the self._infoFrame as the parent into the wx.MessageDialog. Thats it.
First, I added this method to PyBusyInfo class:
def getFrame(self):
return self._infoFrame
Then, I do this code to make it work properly with the error message ABOVE the Busy Info box:
myBusy = PyBusyInfo("Loading, please wait ...", myParentWindow)
wx.MessageDialog(myBusy.getFrame(), "Error message", "Error!", style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
This was a tough issue to solve, but this information should help other people who run across the same problem.
Related
My company is using Python 2.6 (yuck, I know, but it's my constraint). I need to make a little GUI that involves a ComboBox. I chose Tix, because that's what I have--not allowed to grab anything else.
Anyway, I'd like to set the label that the ComboBox has to the top side. According to the documentation at http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm, if I use "labelside" in the ComboBox constructor as a parameter, it should move the label to the top, like I want.
Unfortunately, when I do this, it gives me a strange error:
_tkinter.TclError: cannot assigned to static variable "-labelside"
CONTEXT: this is within a Python class that inherits from Tix.Frame. The first code example works perfectly, the other does not.
My constructor (not including 'labelside') looks like this:
combobox = Tix.ComboBox(self,
label="Available files: ",
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
It works perfectly, as expected. I get a nice ComboBox in my window. The label is the left side, however--not what I want.
So, I try this:
combobox = Tix.ComboBox(self,
label="Available files: ",
labelside='top',
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
That's when it gives me the error. I've scrounged the internet for answers, but have found only users who have the same unanswered question: why is it happening? It would appear that I'm following the documentation correctly.
I also tried substituting Tix.TOP for top, and it gave me the same error.
Any help or ideas would be greatly appreciated!
I writing gtk interface with python code. the problem is:
init entry widget by gtkbuilder:
self.some_entry = self.builder.get_object('SomeEntry')
Define signal by typing button, after then must changed entry color:
def on_SomeButton_clicked(self, widget):
self.some_entry.modify_bg(Gtk.StateType.NORMAL,Gdk.Color(20000,10000,10000))
but it doesn't work, such 'modify_base'. And I don't know why. Help please.
Sorry for my English(
EDIT2:
Turns out it was an entry box giving the problem which is another issue in and of itself because the background is not the property you need to modify but the BASE color property which can typically be set using:
self.entry.override_background_color(Gtk.StateType.Normal, Gdk.RGBA(0.0, 1.0, 0.0, 1.0))
However for OP it was not working so a CSS option was explored, listed at: https://mail.gnome.org/archives/gtk-app-devel-list/2005-November/msg00236.html
EDIT:
So working with PyGtk3 I was able to get a button changing color using you line of code:
self.button.modify_bg(Gtk.StateType.Normal, Gdk.Color(20000, 10000, 10000))
It was grey on initialization and dark red after the code ran. The only thing I could think of is make sure that the object you are trying to modify is actually in a NORMAL state after you run the code and make sure the signal you think is triggering is actually triggering.
==============
Original post:
Without having the full code here there are a few things that could be causing this. I just threw together a test program in Python based off of: http://pygtk.org/pygtk2tutorial/examples/helloworld.py
When I set the Gtk State for the modify_bg I had to use:
gtk.STATE_NORMAL
Not sure if that is due to a different version of Gtk or what though.
Then when I went to use Gdk I had to refer to it as:
gtk.gdk
The line that I ended up with to change the button color was:
self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(20000, 10000, 10000))
Hopefully that works out, in order to get any more detailed though we would definitely need more code and to know what kind of errors you are getting.
CSS works, code below:
style_provider = Gtk.CssProvider()
css = open('style.css', 'rb')
css_data = css.read()
css.close()
style_provider.load_from_data(css_data)
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
With line
"widgetname".get_style_context().add_class("colorize")
"widgetname" has been colorized.
CSS code:
.colorize {
background: rgba(200,50,50,0.3);
}
This is where the error is found:
global backbuttonimg
backbuttonimg = PhotoImage(file="backbutton.gif")
C6 = tkinter.Button(W_CheckDates, image=backbuttonimg, command = CheckDatesBack)
C6.pack()
I don't understand why this isn't working. I have another image in my program here:
def Login():
global W_Menu
W_Menu = Tk()
W_Menu.geometry('160x310+600+200')
W_Menu.title("NSS DB")
A0 = Canvas(W_Menu, width='160', height='160')
A0.pack()
global img
img = PhotoImage(file="nsslogo.gif")
A0.create_image(80,80, image=img)
I also get a similar error when I try to call the above definition after it has already been initially called (for example when my program logs out) so I have readjusted so the window simply deiconifies instead of calling it again, and I do not get the error again. However I am confused as to why I get an error with the former section of code now, as the button simply does not show up whether it is called for the first time or not. Sorry if this is a bit vague, please ask if I have not explained in enough detail. Thanks in advance.
P.S. I have looked in other threads with similar problems but none apply to me.
Ok so you say that the login function works once, then it can't work again. Here the problem can be solved using tk.Toplevel() instead of tk.Tk() see: why python photoimages don't exist? and tkinter.TclError: image "pyimage3" doesn't exist
These threads mention how you can't have two instances of Tk() running simultaneously, you have to use Toplevel() instead.
Why did these threads not apply to you (i think they do...)? But just a tip, if you state that they don't apply to you, then give reasons why, it helps make your question clearer. Also, add the full traceback when your question is about a particular error.
Hope this helps a bit.
Adding this for anyone who has tried the above with no success. If you have an erroneous path when running the script in some environments the path to the file is retained. I commented out everything from where I first use PhotoImage up to the window mainloop, run the script, close resulting gui, uncomment the code, run, and it shows the image as expected.
You can add a master parameter
backbuttonimg = PhotoImage(file="backbutton.gif",master=W_Menu)
Here Cledia
I am also facing this error.
And when I use Toplevel instead of To, it is working well
I suggest you to use TopleToplevel
Use tk.Toplevel() instead of tk.Tk() So its will work because the python coding library tkinter it doesnt make any sens if you make two windows working sametime with the tk.Tk() so you can use the toplevel() to open multiwindows in the same time !!
Hope it's Helpful
My app has a GtkFileChooserButton that you can use to open a chooser widget and pick a single file .. and then perform operations on that file. This works.
I've added drag & drop functionality to the button as well. It works, but it's buggy.
In short, the first dnd to the FileChooserButton triggers the file-set signal and appears to have worked, -- the name changes from "( None )" to the file's name and if you then click on the button, it pops up a chooser widget showing the proper file selected; HOWEVER, as you can see from the debug output below, get_filename() does not return the filename! Not the first time, anyway.
The second time we dnd a file onto the button (whether it's a different file or the same file again), all goes well and get_filename() returns the file's name. Why?
Here's the debug output from my program when I drag three files on to the button, one at a time:
[on_file-set] FileChooserButton.get_filename() output:
None
[on_file-set] FileChooserButton.get_filename() output:
'/home/ryran/Desktop/priv.txt'
[on_file-set] FileChooserButton.get_filename() output:
'/home/ryran/Desktop/kinamppost'
PS: When I did this, the 1st and 2nd dnd were actually the same file.
If you want to see the full app in action, it's at http://github.com/ryran/pyrite, and I'd love to post code, but there's not really anything to post!! I'm not doing drag_dest_set() because FileChooserButton already supports dnd. So ALL I'm doing is defining a cb for the FileChooserButton's file-set signal. So uhh.. here's that:
def action_chooserbtn_file_set(self, widget):
print "[on_file-set] FileChooserButton.get_filename() output:\n{!r}\n".format(widget.get_filename())
For the record I also tried doing all this in concert with defining drag_dest_set, but came up with the same results.
What else to say? I'm starting to think this is a bug.
Turns out this really is a GTK+ bug. Talked to a developer on IRC. He helped me realize that and then encouraged me to post a bug report, which I did -- https://bugzilla.gnome.org/show_bug.cgi?id=669718
This is related to another question I found here that seems to be inactive for a few months, so I think it's worth asking again.
I have created a simple QDialog that has a QTextEdit and a QPushButton. This pops up in my application when a user right-clicks and selects the option to "add comments". I want them to be able to write free-form text and I'll just save whatever they write as a long string with no concern for new lines, etc.
When the user clicks the button, it executes code like this:
self.connect(accept_button,QtCore.SIGNAL('clicked()'),lambda arg=str(view_textedit.toPlainText()): self.updateGroupComments(arg))
def updateGroupComments(self,new_comment_str):
print "Updating user comment to have new string: " + new_comment_str
self.group_entry.list_of_user_comments[self.currentFrameCounter] = new_comment_str
This is not detecting the TextEdit text that is visible (it only detects whatever the text edit text is set to when it is created). How do I make a simple command that returns the currently visible text from a QTextEdit. Again, the function
toPlainText()
is not working correctly... it doesn't find the currently visible text, only whatever text was on screen before changes or additions started being made by the user.
If this can't be done without subclassing and appealing to cursor positions, it makes the whole thing seem worthless... so please keep suggestions only to those implemented without subclassing or manipulating cursors. It should be really simple and straightforward to just return all currently visible text... what am I missing?
Objects that are being bound to default arguments are evaluated at the definition time. The function is working correctly, it returns whatever was in the text field when it was executed. Your code simply calls it at the wrong moment. If you want to use lambda, then do:
self.connect(
accept_button, QtCore.SIGNAL('clicked()'),
lambda: self.updateGroupComments(str(view_textedit.toPlainText()))
)
Or make view_textedit an instance attribute instead, and do simply
self.connect(
accept_button, QtCore.SIGNAL('clicked()'), self.updateGroupComments
)
And change updateGroupComments to call self.view_textedit.toPlainText instead of taking an argument.
BTW, this is not PyQt specific, this is how Python works in general.
To illustrate my last comment, that lambda can very well be replaced with:
def slot():
self.updateGroupComments(str(view_textedit.toPlainText()))
self.connect(accept_button, QtCore.SIGNAL('clicked()'), slot)