I'm quite new to this site, so I hope I follow all the rules whilst asking. On with the problem:
I'm making a GTK+ / Python3 program built with Glade. When the user clicks a button to Read a File, certain time-consuming functions are called. Here's a snippet to give you an idea:
def onReadFile(self, widget, data=None):
### I want the statusbar (had the same problem with a progressbar)
### to push() and display at this point
self.statusbar.push(self.contextID, "Reading file...")
### Unfortunately, my program waits for all this to finish
### before displaying the statusbar.push() far too late
text = back.readFile(self.inFile)
splitText = back.textSplit(text)
choppedArray = back.wordChop(splitText)
back.wordCount(choppedArray, self.currDict)
currSortedArray = back.wordOrder(self.currDict)
handles.printResults(currSortedArray, "resCurrGrid", self.builder)
The main idea is that things aren't happening in the order I expect them to, and I don't know why (the things still happen without errors). I read around (here and there and thought perhaps threading is my problem, but I wasn't sure as I didn't find anyone asking too similar a question as mine.
Why is the statusbar.push()
waiting until the end to display its message?
Update
I've tried to sort it out following a threading example here, but I just can't 'fit' that lesson to the layout of my class-based program.
This is what it's looking like (clipped for brevity and relevance):
from gi.repository import Gtk, GLib, GObject
import threading
import back
import handles
class Application:
def __init__(self):
# I build from glade
self.builder = Gtk.Builder()
...
# I want this window to show later
self.progWindow = self.builder.get_object("progWindow")
self.window = self.builder.get_object("mainWindow")
self.window.show()
# I believe this code should go here in the __init__, though
# I'm quite possibly wrong
thread = threading.Thread(target=self.onReadFile)
thread.daemon = True
thread.start()
...
def upProgress(self):
self.progWindow.show()
return False
def onReadFile(self, widget, data=None):
# Following the example I linked to, this to my understanding
# should show the progWindow by asking the main Gtk thread
# to execute it
GLib.idle_add(self.upProgress)
# Time-consuming operations
text = back.readFile(self.inFile)
splitText = back.textSplit(text)
...
if __name__ == "__main__":
GObject.threads_init()
main = Application()
Gtk.main()
I do get the following error when I threading.Thread(target=self.onReadFile)
, but it's the closest to 'working' I can get it:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.2/threading.py", line 740, in _bootstrap_inner
self.run()
File "/usr/lib/python3.2/threading.py", line 693, in run
self._target(*self._args, **self._kwargs)
TypeError: onReadFile() takes at least 2 arguments (1 given)
My only ideas are that:
- I need quite a bit different structure because I'm using a class (and my example in the link isn't).
- I'm failing to pass a necessary argument, but for the life of me I can't see what.
- I'm failing at life.
If you can help, fantastic, if you can't but can suggest a great tutorial, great. My hair can't take much pulling.
If I should post a full working example, let me know.