not able to hide message box in wxpython - python

hi guys tried everything and now i am asking your suggestions.
I am not able to hide my messagebox.
code is:
ans = wx.MessageBox("length = %s , height = %s " % (str(len), str(ht)))
if ans = wx.Yes:
subprocess.call("pword | sudo -S ./Install.sh %s %s" % (str(len),str(ht)))
3rd line take around 6-7 min to complete .till that time message box will be on screen ,i want to make it hide till installation process get finish.
I tried hide ,future call,close ,Disable..but everytime i get 'int object has no attribute " ".

The message box must be hidden and destroyed by the time wxMessageBox() returns, there must be something else going on here.
In general, if you want to be sure that all pending events have been processed (and so all windows that should be repainted/resized/closed were indeed handled), use wx.CallAfter() to launch your long-running process at a slightly later time.
Of course, running a blocking operation taking several minutes from a GUI program is a bad idea anyhow, but this is another story...

If you need more control over the message box use a message dialog instead. The message box returns the answer directly, so you can't control the window. Creating a message dialog lets you control the window.
Here is a simple example:
import wx
app = wx.App(False)
box = wx.MessageDialog(None, 'Yes or No?', caption='Dialog Title', style=wx.YES_NO | wx.YES_DEFAULT)
result = box.ShowModal()
box.Destroy()
if result == wx.ID_YES:
print 'yes'
else:
print 'no'

Related

How to show the current window in Tkinter?

Hope you can help me with the following issue.
I'm using the library tkinter and
I have a main_screen main_screen= Tk() which is looping with mainloop()
Inside of the main_screen, there is a little data form where you need to type some necessary data.
And at the end of the window, I have a button to open a second window.
Once I click in that button, report_screen appears (See below in my code)
The new window should appear with the command Toplevel() and print a label that says Starting:
request_start = LabelFrame(report_screen, text="Starting...").pack()
then my program must run a process where it takes around 10 seconds to complete it.
Let's suppose that my process is just this
time.sleep(10)
And finally, run the next line:
request_done = LabelFrame(report_screen, text="Done").pack()
What is my problem?
The problem is that report_screen doesnt appear until the process of 10 sec has finished, and appears with both labels "Starting..." and "Done" at the same time.
I don't want that, I require that report_screen appears with the label "Starting", and then run the process, and when the process finished, add the "Done" label
This is the part of my code where I have this issue
report_screen = Toplevel()
request_start = Label(report_screen, text="Starting...").pack()
time.sleep(10) #example of my process that takes around 10 seconds
request_done = Label(report_screen, text="Done").pack()
Using update() method works to update whatever is in the screen

how do I print a title for the top of my running program to continuously be visible for a code that prints and runs an endless amount of data?

Example: (to stay visible on the running program, able to view it at anytime if needed to scroll to the top)
print("this is my title")
print("here is my sub title")
count = 0
while count < 5000:
print("hello")
count = count + 1 # or count += 1
My code runs for as long as I set it too, that's not the problem. But when the program runs, it never shows the top printed title, or if I were to stop the program for a moment and physically scroll to the top, that printed title and other various text isn't visible.
How do I fix this to where, even if I wanted to print a million items, I could still see the printed title and printed information at the top?
First a useful non python way:
If you run a script (say my_long_print_script.py) from the terminal you can use less (in linux and osx for sure):
python my_long_print_script.py | less
then use enter to scroll down and q to quit.
Writing to stdout in python
In python you can directly write to stdout and 'overwrite' your previous output. This can lead to some sort of progress bar behaviour, I'm not sure this is what you want, here is an example:
# content of my_long_print_script.py:
import sys
from time import sleep
sys.stdout.write('This title should stay\n')
sys.stdout.write('this subtitle too\n')
for count in xrange(100):
sleep(0.1)
sys.stdout.write('{0}\r'.format(count))
sys.stdout.flush()
When you run this as a script (so you type python my_very_long_print_script.py in the terminal) the two title lines will persist and below a single line will continuously be updated.
FYI: I added the sleep because the count changes too quickly otherwise.
Hope this was somehow useful.
You'll probably want to use python's curses library. This is how you create "windows" that can be redrawn in-place.
I wrote a CLI version of 2048 that would scroll the terminal every time I output the game's board after a move. Using curses, I can now just overwrite the previous board without any scrolling.
Basically you'll want to initialize a new curses window object, set your output string to "My Title Here" and issue a window.redraw() command at (0,0) every time your program iterates.

wx Python MessageDialog popping up behind BusyInfo box?

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.

changing colour of ttk.Progressbar elements in the xpnative theme - python

I'm using python 2.7 and TK to make a gui which accesses text files and uses data in them to do many things, but the one relevant here is sending a gchat message.
Currently, I have everything working, the point I need some help with is when I call my module to send the message, the message is sent perfectly, although I wanted the user to have an indication of the process happening, so I created a ttk.progressbar. but there is a few things I'd like to improve on this:
1) I would like to change the appearance of the actual bar, upon viewing the source files, I couldn't see any options, and when I googled the problem the only fix I could find was to change the source code, I'm pretty sure this would only change it when ran with my files, then when the user runs it, it would be the standard? preferably, I'd like the bar to be transparent, although blue would work, I've seen some people having blue as a state in window machines, windows is my main concern, so if I could get say, blue in windows, but native elsewhere, that would be fine.
2)this one is hopefully a bit more simple, but when the button is pressed it takes values from user input which can still be changed, maybe altering the outcome of the function, is there anyway to stop all input to a tk window, then resume when the function is complete?
below is what I have so far, thank you for the help
self.progressbar = ttk.Progressbar(self.gcTableButtonsFrame, length = 70, orient=HORIZONTAL, mode ='determinate')
self.progressbar.grid(column = 0, row = 0, sticky = 'n s')
#we then pass through the extension and the string 'test' through this fnction from the gchat module which will then send a
#gchat message to the extension passed through
self.bytes = 0
self.maxbytes = 0
self.start()
self.t = thread.start_new_thread(gchat.sendGChatMessage,(text, "test"))
except IndexError:
tkMessageBox.showinfo("Invalid Entry", "Please first select an Entry to send to")
def start(self):
self.progressbar["value"] = 0
self.maxbytes = 50000
self.progressbar["maximum"] = 50000
self.read_bytes()
def read_bytes(self):
'''simulate reading 500 bytes; update progress bar'''
selection2 = self.gcTable.selection()
self.bytes += 700
self.progressbar["value"] = self.bytes
if self.bytes < self.maxbytes:
# read more bytes after 100 ms
Tk.after(self.mainPyWindow, 100, self.read_bytes)
else:
tkMessageBox.showinfo("Message Sent", "A GChat message has been sent to " + self.gcTable.item(selection2, 'values')[1])
self.progressbar.destroy()
Your first question is somewhat ambiguous, in that I'm not sure whether you are talking about controlling the look of the progress bar or the nature of the progress it is displaying.
The nature of the progress bar is controlled via its value and its mode option (determinate progress bars are different from indeterminate ones; the former are controlled via the value, the latter just show that “something is happening”).
The look of a progress bar is controlled by the overall theme. On Windows and Mac OS X, the default theme is the system theme meaning that the progress bar will look native, whatever that is. I've not experimented recently with themes on Linux so I forget what they look like there; switch themes with:
# Switch to the included 'clam' theme
s = ttk.Style()
s.theme_use('clam')

better way to update a Tkinter listbox

Hi
so first of all i made a program that downloads music and displays the percent that has downloaded in a list box.
kind of like this
from Tkinter import *
from urllib2 import *
admin = Tk()
Admin = Tk()
listbox = Listbox(admin, bg="PURPLE")
listbox.pack()
def fores():
chunks = 10000
dat = ''
song = '3 rounds and a sound'
url = 'http://bonton.sweetdarkness.net/music/Blind%20Pilot%20--%203%20Rounds%20and%20A%20Sound.mp3'
down = urlopen(url)
downso = 0
tota = down.info().getheader('Content-Length').strip()
tota = int(tota)
while 1:
a = down.read(chunks)
downso += len(a)
if not a:
break
dat += a
percent = float(downso) / tota
percent = round(percent*100, 1)
listbox.insert(END, percent)
listbox.update()
listbox.delete(0, END)
listbox.insert(END, percent)
listbox.update()
button = Button(Admin, text='Download', command=fores)
button.pack()
button = Button(Admin, text='Download', command=fores)
button.pack()
mainloop()
I wont show you the original program for it is over the limit of the post size.
On my original program if i move the window before i download an mp3 file it downloads less then 3 % and stops and if i then close the window it starts downloading again.
does anyone know why this is or if there is an alternative to displaying the percentage on the Tkinter window?
Please help
and update_idletasks doesent work
The proper widget for displaying a string is a Label. You can change the text at runtime with the configure method:
self.progress = Label(...)
...
self.progress.configure(text="%s%% completed" % percent)
Second, you are creating two root windows - admin and Admin. And strangely, you are putting the listbox in one and the buttons in another. Tk isn't designed to work like that. Third, you need to call the mainloop method of your (single) root window (eg: Admin.mainloop)
Finally, as to your comment that update_idletasks doesn't work -- please define "doesn't work". It will in fact update the display. What it won't do is let you interact with the window while it is running.
I made changes to your code based on the above comments (created only one root, used a Label rather than Listbox, and used update_idletasks and the program ran to completion, downloading the song.
The danger of calling update is this: what if you click the "download" button while you are already downloading? What happens is the next time update is called, that button press will be serviced. In the servicing of that event you'll enter an infinite loop. While that inner infinite loop is running the outer one cannot run. You will have effectively frozen the first download.
The proper solution involves one of (at least) two techniques. One, create a thread to do the downloading, and have it periodically send information back to the main loop so it can update the progress bar. The second is to leverage the already existing infinite loop -- the event loop -- and do your reading of chunks one at a time by placing jobs on the event queue with after.
There are examples on the internet for both approaches.
i use a ttk.Progressbar, all you have to do is associate a variable to it and update that particular variable.
http://docs.python.org/library/ttk.html#progressbar
http://www.tkdocs.com/tutorial/morewidgets.html#progressbar

Categories