File Dialog?


https://forum.reallusion.com/Topic415226.aspx
Print Topic | Close Window

By Kelleytoons - 7 Years Ago
So I'm just now getting back to programming (sigh -- and my brain is fried) and for the life of me I can't get a simple file dialog box to work as it works in Blender.  Anyone had any luck?

It shouldn't be rocket science:
import tkinter as tk
from tkinter import filedialog
file_path = tkinter.filedialog.askopenfilename()
file_path = filedialog.askopenfilename()

(neither works although they both work in Blender).
By videodv - 7 Years Ago
Kelleytoons (6/13/2019)
So I'm just now getting back to programming (sigh -- and my brain is fried) and for the life of me I can't get a simple file dialog box to work as it works in Blender.  Anyone had any luck?

It shouldn't be rocket science:
import tkinter as tk
from tkinter import filedialog
file_path = tkinter.filedialog.askopenfilename()
file_path = filedialog.askopenfilename()

(neither works although they both work in Blender).



Hi Mike

I think you just need to add

import tkFileDialog

Chris.
By Kelleytoons - 7 Years Ago
No, that doesn't work (tried that as well earlier -- sorry, but I didn't outline all the things I tried which didn't work).  For one thing, you have to import that dialog function from *somewhere* (you'll get an error if you just

import tkFileDialog

So you could try:

from tkinter import *
or
from tkinter import tkFileDialog

but the second is redundant (and doesn't work anyway).

Someone MUST have done this already, right?
By Kelleytoons - 7 Years Ago
I give up -- I'll just use the file dialog box built-in to RL's Python (not exactly what I had in mind but it will do for now).
By videodv - 7 Years Ago
Hi Mike
I got this piece of code snippets that run from python not from Iclone.

# import tkinter
# import tkFileDialog

# from tkinter import filedialog
# from tkinter import *

# def main():

    # #tkinter.tk().withdraw() # Close the root window
    # in_path = tkFileDialog.askopenfilename()
    # print(in_path)

# if __name__ == "__main__":
    # main()

# from tkinter import filedialog
# from tkinter import *
# from tkinter import colorchooser
# import tkinter as tk
# import os

# application_window = tk.Tk()

# #Build a list of tuples for each file type the file dialog should display
# my_filetypes = [('all files', '.*'), ('text files', '.txt')]

# # Ask the user to select a folder.
# answer = filedialog.askdirectory(parent=application_window, initialdir=os.getcwd(), title="Please select a folder:")

# # Ask the user to select a single file name.
# answer = filedialog.askopenfilename(parent=application_window, initialdir=os.getcwd(), title="Please select a file:", filetypes=my_filetypes)

# # Ask the user to select a one or more file names.
# answer = filedialog.askopenfilenames(parent=application_window, initialdir=os.getcwd(), title="Please select one or more files:", filetypes=my_filetypes)

# # Ask the user to select a single file name for saving.
# answer = filedialog.asksaveasfilename(parent=application_window, initialdir=os.getcwd(), title="Please select a file name for saving:", filetypes=my_filetypes)

# rgb_color, web_color = colorchooser.askcolor(parent=application_window, initialcolor=(255, 0, 0))

# root = Tk()
# root.filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
# print (root.filename)

#Here is an example of storing the directory path as a global variable and using that to populate a Label.

from tkinter import filedialog
from tkinter import *

def browse_button():
    # Allow user to select a directory and store it in global var
    # called folder_path
    global folder_path
    filename = filedialog.askdirectory()
    folder_path.set(filename)
    print(filename)


root = Tk()
folder_path = StringVar()
lbl1 = Label(master=root,textvariable=folder_path)
lbl1.grid(row=0, column=1)
button2 = Button(text="Browse", command=browse_button)
button2.grid(row=0, column=3)

mainloop()

Not sure if this helps but as you know I am new to python and tkinter.

Chris.
By Kelleytoons - 7 Years Ago
So, unfortunately, the RL file open dialog doesn't have what I really need, which is the ability to tell the user what I want them to do (the box heading).  Anyone have an idea how I would emulate the tk approach (giving the fileopen box a title)?
By Kelleytoons - 7 Years Ago
videodv (6/13/2019)
Hi Mike
I got this piece of code snippets that run from python not from Iclone.

# import tkinter
# import tkFileDialog

# from tkinter import filedialog
# from tkinter import *

# def main():

    # #tkinter.tk().withdraw() # Close the root window
    # in_path = tkFileDialog.askopenfilename()
    # print(in_path)

# if __name__ == "__main__":
    # main()

# from tkinter import filedialog
# from tkinter import *
# from tkinter import colorchooser
# import tkinter as tk
# import os

# application_window = tk.Tk()

# #Build a list of tuples for each file type the file dialog should display
# my_filetypes = [('all files', '.*'), ('text files', '.txt')]

# # Ask the user to select a folder.
# answer = filedialog.askdirectory(parent=application_window, initialdir=os.getcwd(), title="Please select a folder:")

# # Ask the user to select a single file name.
# answer = filedialog.askopenfilename(parent=application_window, initialdir=os.getcwd(), title="Please select a file:", filetypes=my_filetypes)

# # Ask the user to select a one or more file names.
# answer = filedialog.askopenfilenames(parent=application_window, initialdir=os.getcwd(), title="Please select one or more files:", filetypes=my_filetypes)

# # Ask the user to select a single file name for saving.
# answer = filedialog.asksaveasfilename(parent=application_window, initialdir=os.getcwd(), title="Please select a file name for saving:", filetypes=my_filetypes)

# rgb_color, web_color = colorchooser.askcolor(parent=application_window, initialcolor=(255, 0, 0))

# root = Tk()
# root.filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
# print (root.filename)

#Here is an example of storing the directory path as a global variable and using that to populate a Label.

from tkinter import filedialog
from tkinter import *

def browse_button():
    # Allow user to select a directory and store it in global var
    # called folder_path
    global folder_path
    filename = filedialog.askdirectory()
    folder_path.set(filename)
    print(filename)


root = Tk()
folder_path = StringVar()
lbl1 = Label(master=root,textvariable=folder_path)
lbl1.grid(row=0, column=1)
button2 = Button(text="Browse", command=browse_button)
button2.grid(row=0, column=3)

mainloop()

Not sure if this helps but as you know I am new to python and tkinter.

Chris.


Chris,
None of that works in iClone, unfortunately (it all works in Blender, which is what I am familiar with).  And, unfortunately, RL's implementation of file open doesn't do me much good (it won't tell the user what the heck file you are looking for so you had better damn well know what the point of the file open is as the script runs).

I still can't believe this is what we have to deal with, so clearly I'm doing something wrong.  But I have no idea how to make it work in iClone.

By videodv - 7 Years Ago
Hi Mike

Maybe this Link may point you in the right direction.

Think I will take some time myself and see if I can work this out.

Chris.
By videodv - 7 Years Ago
Hi Mike

From the link above I had a tinkle with the code


import PySide2, RLPy, os
from PySide2 import *
from PySide2.QtWidgets import *
from PySide2.shiboken2 import wrapInstance

class filedialogdemo(QWidget):
   def __init__(self, parent = None):
      super(filedialogdemo, self).__init__(parent)
       
      layout = QVBoxLayout()
      self.btn = QPushButton("QFileDialog static method demo")
      self.btn.clicked.connect(self.getfile)
       
      layout.addWidget(self.btn)
      self.le = QLabel("Hello")
               
      self.contents = QTextEdit()
      layout.addWidget(self.contents)
      self.setLayout(layout)
      self.setWindowTitle("File Dialog demo")
       
   def getfile(self):
      fname = QFileDialog.getOpenFileName(self, 'Open file Mike Kelly',
         'c:\\',"Image files (*.jpg *.gif)")
      #self.le.setPixmap(QPixmap(fname))


global invisable_dialog

set_screen_widget = filedialogdemo()

invisable_dialog = RLPy.RUi.CreateRDialog()
invisable_dialog.SetWindowTitle("Make Invisable")

#-- Create Pyside layout for RDialog --#
pyside_dialog = wrapInstance(int(invisable_dialog.GetWindow()), QtWidgets.QDialog)
sample_layout = pyside_dialog.layout()

#-- Assign the setscreenwidget class to PySide Dialog --#
sample_layout.addWidget(set_screen_widget)

invisable_dialog.Show()

This produces a file dialog from within Icone and as you can see you can set the title ect.

Chris.
By Kelleytoons - 7 Years Ago
Thanks, Chris, for all your effort in this -- it's too late here for me to try this out (too much sitting for my knee recovery) but I'll look at it tomorrow.

It's a TON of work to go through for a simple dialog, though.  I still hope there's an easier way.
By The-any-Key - 7 Years Ago
You can alos use the built in dialogs in PySide2.
All you need is some scripts:
# Basic import
import RLPy
import PySide2
from PySide2 import *
from PySide2.shiboken2 import wrapInstance
# Load UI files
import os
def get_save_filename_dialog(title, filter, default_filename):
return PySide2.QtWidgets.QFileDialog.getSaveFileName(None,str(title),str(default_filename),str(filter))
def get_load_filename_dialog(title, filter, default_filename):
return PySide2.QtWidgets.QFileDialog.getOpenFileName(None,str(title),str(default_filename),str(filter))
def save_file(filename, text):
file = open(filename,'w')
file.write(text)
file.close()
def load_file(filename):
file = open(filename,'r')
text=file.read()
file.close()
return text

Here is how to create a load dialog and load the data:
# Select file
load_file=get_load_filename_dialog("Load dialog title","My file ending (*.mfe)","Default load name.mfe")
if load_file[0]:
# Get only filename
load_filename=load_file[0]
# Load file
data_string=load_file(load_filename)

Here is how to create a save data with a save dialog:
# Open save file dialog
save_filename=get_save_filename_dialog("Save dialog title","My file ending (*.mfe)","Default save name.mfe")
# Check if provided filename
if save_filename:
save_file(save_filename[0],data_string)
By Kelleytoons - 7 Years Ago
Any,

I'm not trying to either save or load files -- just get the file names.  But I'm sure that info will help someone if they come across this thread.
By Kelleytoons - 7 Years Ago
videodv (6/13/2019)
Hi Mike

From the link above I had a tinkle with the code


import PySide2, RLPy, os
from PySide2 import *
from PySide2.QtWidgets import *
from PySide2.shiboken2 import wrapInstance

class filedialogdemo(QWidget):
   def __init__(self, parent = None):
      super(filedialogdemo, self).__init__(parent)
       
      layout = QVBoxLayout()
      self.btn = QPushButton("QFileDialog static method demo")
      self.btn.clicked.connect(self.getfile)
       
      layout.addWidget(self.btn)
      self.le = QLabel("Hello")
               
      self.contents = QTextEdit()
      layout.addWidget(self.contents)
      self.setLayout(layout)
      self.setWindowTitle("File Dialog demo")
       
   def getfile(self):
      fname = QFileDialog.getOpenFileName(self, 'Open file Mike Kelly',
         'c:\\',"Image files (*.jpg *.gif)")
      #self.le.setPixmap(QPixmap(fname))


global invisable_dialog

set_screen_widget = filedialogdemo()

invisable_dialog = RLPy.RUi.CreateRDialog()
invisable_dialog.SetWindowTitle("Make Invisable")

#-- Create Pyside layout for RDialog --#
pyside_dialog = wrapInstance(int(invisable_dialog.GetWindow()), QtWidgets.QDialog)
sample_layout = pyside_dialog.layout()

#-- Assign the setscreenwidget class to PySide Dialog --#
sample_layout.addWidget(set_screen_widget)

invisable_dialog.Show()

This produces a file dialog from within Icone and as you can see you can set the title ect.

Chris.


Okay, maybe it's the drugs I'm still taking for my knee, but I don't for the life of me see how to get the name of the file picked from that dialog.  Do you have an example of that, Chris?

That's all I really want to do, something like:

file_name = getfiledialog("Set Title").


I can't imagine this is THAT difficult when it clearly isn't if I could use the supposedly built in tkinter (which I can't for some reason).

By The-any-Key - 7 Years Ago
Kelleytoons (6/15/2019)
Any,

I'm not trying to either save or load files -- just get the file names.  But I'm sure that info will help someone if they come across this thread.

You dont need to save or load the file. The get_save_filename_dialog and get_load_filename_dialog will just open a dialog where the user can select a file. Then the script will return the path in load_file[0] or save_filename[0] that you can use for whatever you need a filepath with.

Maybe I am missing the idea. I thought you wanted a dialog where the user can select a file? Or do you just want to display a treeview with files and folders?
By Kelleytoons - 7 Years Ago
Sorry, Any -- after my surgery the drugs I'm taking are clouding my mind.  For some reason all I could see was the file reading and writing you were doing.

Let me play a bit -- I only have a limited amount of time I can sit upright but it would be nice to get this working.
By Kelleytoons - 7 Years Ago
I may have to wait until the drugs wear off.

I can get it to work... after a fashion.  I cannot discern how it's choosing the directory to start in, which is Bad.  I thought maybe I could do this by specifying a file pattern in the default file but this doesn't appear to do anything useful (using another drive letter just got me to my Dropbox and not even on that drive, which is really, really weird -- prior to that it just appeared to pick the Python directory I was running in iClone).

I'll have to most likely learn Pyside, I see, but this drug-addled brain ain't gonna do that right now.  
By videodv - 7 Years Ago
Hi Mike

The filename returned if you look at the example is fname

Chris
By Kelleytoons - 7 Years Ago
Okay, so thanks for all the help, Chris and Any.  I think I have it working for what I want (I added the Dir to the example Any posted).

I suspect I will have to learn Pyside if nothing more than to do some UI for things (there was a reason I ALWAYS left the UI and the print functions to my staff, as I hate that part of programming).  But I at least have something workable for now.
By The-any-Key - 7 Years Ago
Tested to set a default folder and I can't seem to get it to work. You use setDirectory but it seems I only get an error when trying to set the folder.

EDIT:
But it seems you only need to add the path in the default filename: ex "C:\\Windows\\test.txt"
By Kelleytoons - 7 Years Ago
This is what I did:

def get_load_filename_dialog(title, filter, default_filename,dir):
    return PySide2.QtWidgets.QFileDialog.getOpenFileName(None,str(title),str(dir),str(default_filename),str(filter))

And then this call:
loadDir = "V:\\exports"
load_file=get_load_filename_dialog("Legs Diffuse","","*.jpg",loadDir)

sets the directory.  Now, in my drug-addled state, I'm not sure why this works (indeed it appears as if it should NOT work) but it works for me just fine.  Again, I'm going to need to learn Pyside I can see, just not right now.
By The-any-Key - 7 Years Ago
Kelleytoons (6/15/2019)
This is what I did:

def get_load_filename_dialog(title, filter, default_filename,dir):
    return PySide2.QtWidgets.QFileDialog.getOpenFileName(None,str(title),str(dir),str(default_filename),str(filter))

And then this call:
loadDir = "V:\\exports"
load_file=get_load_filename_dialog("Legs Diffuse","","*.jpg",loadDir)

sets the directory.  Now, in my drug-addled state, I'm not sure why this works (indeed it appears as if it should NOT work) but it works for me just fine.  Again, I'm going to need to learn Pyside I can see, just not right now.

It works because the dir is in the filename argument spot. You will notice that your filter in the dialog now got the filename as filter. Proboply not what you want. But I updated the script so you can provide a default folder:
def get_save_filename_dialog(title, filter, default_filename, default_folder=None):
# Filter example: "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
fileDialog=PySide2.QtWidgets.QFileDialog()
if default_folder:
# Check if default folder end with \\
if default_folder.endswith("\\"):
default_filename=default_folder+default_filename
else:
default_filename=default_folder+"\\"+default_filename
return fileDialog.getSaveFileName(None,str(title),str(default_filename),str(filter))
def get_load_filename_dialog(title, filter, default_filename, default_folder=None):
# Filter example: "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
fileDialog=PySide2.QtWidgets.QFileDialog()
if default_folder:
# Check if default folder end with \\
if default_folder.endswith("\\"):
default_filename=default_folder+default_filename
else:
default_filename=default_folder+"\\"+default_filename
return fileDialog.getOpenFileName(None,str(title),str(default_filename),str(filter))
By Kelleytoons - 7 Years Ago
The filter seems to work just fine, as does the rest, so I'm not sure why I need anything else.

However -- there IS one thing I would like, and it's to be able to select multiple files (as you can in any normal file explorer window).  I don't see a way for Pyside to allow that but, again, I suspect I'm going to need to learn all of it as soon as I heal up.
By Kelleytoons - 7 Years Ago
Ah, okay, got multiple files returned.  Even as doped up as I am, I seem to be making lots of progress.  But now I'm really hungry.  REALLY hungry.  Need to eat.
By animagic - 7 Years Ago
Thanks for the File Dialog question and solutions. I was looking for this as well and was surprised that it isn't more straightforward.

 If RL ever fixes the API for visemes (GetVisemeKey() function), I would like to add the capability to select a file from a dialog for the Papagayo script.