pyside widget.show not blocking - python

I wrote a little application, that saves small videos it generates. The code pasted should do the following:
show dialog to the user to choose a directory
if directory is not empty show widget that has a circle running around so there's a feedback that something is going on
then generate the movies (which takes some time and most if it has handled with multiprocessing pool)
(not included in snippet, but the code would go on to do more background stuff, so the loading widget would stay on for a while
Code:
def saveMovie(self):
self.pause()
if not os.path.exists("outputs"):
os.makedirs("outputs")
dir = QtGui.QFileDialog.getExistingDirectory(self,dir="outputs",options=QtGui.QFileDialog.ShowDirsOnly)
if not dir == '':
self.loading = True
self.loadingWidget.show()
name = os.path.basename(dir) + "_"
settings = sm.fetch_settings()
swarms,l,l1,l2 = self.generate_movies()
Now instead of this, what happens is that the dialog disappears and the loading widget is shown only after the program has existed from self.generate_movies(). What am I missing?

Related

How do I combine multiple custom tkinter gui functions (windows) into a more "object oriented program" fashion

My project has multiple tkinter functions that create windows and different buttons have different buttons that connect to the main program. One issue I have is that when I call a tkinter gui function the images are not displayed.
def get_userInfo(user,pass):
login_state = db.login_verification(user,pass) # Returns either True / False
if login_state == True:
full_name = db.retrive(user,pass,id) # Get's Full name from database.
gui.user_page(first_name) # This only displays the window with no images / text.
gui.user_page("john") # This works perfectly tho
When I call a function within a function the images from the assets path do not load.
Whereas if I just do gui.user_page from outside the function it works without any issues.
I think if I were to use more classes in my gui.py file it should probably fix the issue.

How do I layout, and close this dialogbox in PyQt?

I'm writing a Flash Card application using Python and PyQt and I have a problem with dialogboxes. First, here's the section of my code which concerns the aforementioned dialogbox:
def openFile(self):
dialog = QDialog()
dialog.setGeometry(200, 100, 50, 100)
list = QListWidget(dialog)
for file in files:
list.addItem(file.replace('.flashcard', ''))
list.itemClicked.connect(self.listClicked)
dialog.exec_()
def listClicked(self, item):
file_to_read = item.text() + '.flashcard'
self.flashcard_list = FlashCard.read_card(file_to_read)
self.front_text.clear()
self.back_text.clear()
self.front_text.insertPlainText(self.flashcard_list[0].front)
self.back_text.insertPlainText(self.flashcard_list[0].back)
Although I'm using PyCharm, I can't actually debug the code since deubgging these sorts of applications is beyond my skill level. That's why I don't know why when I add codes like dialog.setLayout(layout) to the script, it won't run and it doesn't produce any errors. Also, I would like to know how to close this dialogbox since if I change the dialog to self.dialog to carry it over to another function, the code won't run, again, without producing any errors.
Thanks for your help.

How do I hook into tkinters FileDialog?

Using python 3 and tkinter I'm trying to create a file dialog that lets the user select existing directories (exists=True).
When they select choose I'd like to check that the directory is also readable and I can get a file lock. Since the rest of my program will rely read access to the path and it's processes will take a long time.
Whey they select cancel I'd like the dialog to close.
If the directory is not readable I'd like the file dialogue to display a askretry message. Clicking Retry will take them back to choose a file. clicking Cancel will close the dialogue.
In my first attempt, a novice to tkinter, I created this:
import os
from tkinter import filedialog
from tkinter import messagebox
class OpenDialog(object):
def __init__(self):
self.directory_path = None
self.dialog_title ="Photos Directory Selection"
def ask_for_directory(self):
while not self.directory_path:
self.directory_path = filedialog.askdirectory(mustexist=True, title=self.dialog_title)
if not os.access(os.path.dirname(self.directory_path), os.F_OK):
self.directory_path = None
if not messagebox.askretrycancel(title=self.dialog_title, message="Can't read directory."):
break
Although its not perfect. It won't let you cancel the file dialogue.
But alas, I thought I could potentially hook into the file dialogue itself...
I just can't see how I could cleanly hook into the FileDialogue class to cleanly display a askretry dialogue and repeat the process.
filedialogue.py
If there is something I'm missing please share :-)
This works, but does anyone see an issue with recursive call?
def ask_for_directory(self):
self.directory_path = filedialog.askdirectory(mustexist=True, title=self.dialog_title)
if self.directory_path:
# Check that we have access to the path
if not os.access(self.directory_path, os.R_OK):
# If we don't have access
if messagebox.askretrycancel(title=self.dialog_title, message="Can't read directory."):
self.ask_for_directory()
EDIT:
Here is my example but corrected to work...
def ask_for_directory(self):
while not self.directory_path:
self.directory_path = filedialog.askdirectory(mustexist=True, title=self.dialog_title)
if self.directory_path:
if not os.access(self.directory_path, os.R_OK):
self.directory_path = None
if not messagebox.askretrycancel(title=self.dialog_title, message="Can't read directory."):
break
else:
break

PyGTK + threading; windows unexpectedly freezes

I'm trying to manage files containing "other files" (lots of small files stored in a few large files). The "engine" works quite good, but I have some problems with GUI. Some functions are threaded because of processing time, for example deleting or adding files. Here's part of the code:
import gtk, os, data, time, threading, subprocess
import Image, re
gtk.gdk.threads_init()
#some unimportant code - creating window with some buttons and IconView item (to show elements in currently opened directory)
def _del_thread(self): #deletes items selected in gtk.IconView
dl, fl = self.items #self.items stores selected dirs and files
for d in dl:
self.changestatus('Deleting: '+data.dirs[d][0]+'...') #prints the text at StatusBar (data.dirs[d][0] is a filename)
data.RemoveDir(d) #recursively removes all content in directory d
for f in fl:
self.changestatus('Usuwanie pliku: '+data.files[f][0]+'...')
data.PopFile(f) #removes single file
self.changestatus('') #clears the StatusBar
self.refresh() #some elements are deleted - refresh IconView
def _add_thread(self, fl): #adds files listed in fl
for f in fl:
self.changestatus('Adding: '+f[-50:]+'...')
#some unimportant code (recognizing file's extension and generating a thumbnail
data.PutFile(f, thumb, self.dir) #adds the file with generated thumbnail to currently opened directory (self.dir)
self.changestatus('') #clears the StatusBar
self.refresh() #some elements are added - refresh IconView
def Delete(self, widget): #triggered by clicking a context-menu item
md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, \
gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, \
"Do you want to remove selected items?")
res = md.run()
md.destroy()
if res == gtk.RESPONSE_OK:
t = threading.Thread(target=self._del_thread) #start new thread
t.start()
def Add(self, widget): #triggered by clicking a context-menu item
chooser = gtk.FileChooserDialog(title='Select files to add...',action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
chooser.set_select_multiple(True)
response = chooser.run()
if response == gtk.RESPONSE_OK:
#star new thread with selected files' list as an argument
t = threading.Thread(target=self._add_thread, args=(chooser.get_filenames(),))
t.start()
chooser.destroy()
There's also third function run in a thread, but it's unimportant. It is fast (~1 sec), always executes fine and never freezes the window. The other two ones (shown above) sometimes executes well, sometimes not. For example, I select some files in FileChooserDialog, the adding thread starts, StatusBar showing consecutively the files are being added now, and at the end the window freezes. After that the window looks like that (sorry for the polish description):
Why does thread sometimes process without problems, and sometimes doesn't?
Best regards,
mopsiok
I think I found the problem. According to http://faq.pygtk.org/index.py?file=faq20.006.htp&req=show , I had to add gtk.threads_enter() before every gtk function in thread, and gtk.threads_close() after it. Now it seems to work fine.

python gui tree walk

I am trying to figure out how to walk a tree and then display the output in a window that a user can navigate through much like that on the left hand side of my computer. Eventually I plan to have a fully browsable window just like you have on the right hand side. Here is what I have so far, I guess it is a mix of pseudo and actual code. This is for use on a Linux machine using python. I'm not looking for any code but mainly help as to how I can accomplish this with tkinter. Perhaps it is just me but I cannot find much help that helps me solve my problem - most just tell me how to display the directories etc. Any help would be greatly appreciated.
I want this window to look like this
My Documents <--------starting directory
My pictures<------subdirectory
picture1.jpg<-inside of subdirectoy
picture2.jpg
1234.exe<---------random file inside of my documents
I want to have a small folder picture next to a directory or a subdirectory also.
start at root
create window with tk
for dirname,subdirList,filelist in os.walk(root)
create new item(dirname)
for i in subdirList: #not sure what I would have to do to only
have subdirs showing once the directory was
clicked once
append i to item 1
for fname in fileList:
append fname to item 1
else:
item +=1
You can do it using the widget ttk.Treeview, there is a demo dirbrowser.py that does that. So all I can do here is give a stripped version of it and explain how it works. First, here is the short version:
import os
import sys
import Tkinter
import ttk
def fill_tree(treeview, node):
if treeview.set(node, "type") != 'directory':
return
path = treeview.set(node, "fullpath")
# Delete the possibly 'dummy' node present.
treeview.delete(*treeview.get_children(node))
parent = treeview.parent(node)
for p in os.listdir(path):
p = os.path.join(path, p)
ptype = None
if os.path.isdir(p):
ptype = 'directory'
fname = os.path.split(p)[1]
oid = treeview.insert(node, 'end', text=fname, values=[p, ptype])
if ptype == 'directory':
treeview.insert(oid, 0, text='dummy')
def update_tree(event):
treeview = event.widget
fill_tree(treeview, treeview.focus())
def create_root(treeview, startpath):
dfpath = os.path.abspath(startpath)
node = treeview.insert('', 'end', text=dfpath,
values=[dfpath, "directory"], open=True)
fill_tree(treeview, node)
root = Tkinter.Tk()
treeview = ttk.Treeview(columns=("fullpath", "type"), displaycolumns='')
treeview.pack(fill='both', expand=True)
create_root(treeview, sys.argv[1])
treeview.bind('<<TreeviewOpen>>', update_tree)
root.mainloop()
It starts by listing the files and directories present in the path given by sys.argv[1]. You don't want to use os.walk here as you show only the contents directly available in the given path, without going into deeper levels. The code then proceeds to show such contents, and for directories it creates a dummy children so this Treeview entry will be displayed as something that can be further expanded. Then, as you may notice, there is a binding to the virtual event <<TreeviewOpen>> which is fired whenever the user clicks an item in the Treeview that can be further expanded (in this case, the entries that represent directories). When the event is fired, the code ends up removing the dummy node that was created earlier and now populates the node with the contents present in the specified directory. The rest of the code is composed of details about storing additional info in the Treeview to make everything work.
I think tkinter would be a bad choice for this. Other libraries like wxPython, PyQt or GTK does have GUI components which will help you achieve this with minimum effort.

Categories