pythonuser-interfacetkinterfilepathfiledialog

Tkinter: print (.txt) filepath to text widget AND (.txt) file content to scrolledtext widget in the same gui with one filedialogue access


As a follow-up question to this: Python tkinter - how to send StringVar() content to Scrolled Text box using grid() and using procedural code

  1. I know how to print the filepath to a text widget field GUI.
  2. I know how to put the contents of a text file into a scrolledtext widget field in a GUI.
  3. I don't know how to do them at the same time...

I can browse twice, in the same programme, to achieve the goal; but that's not really achieving the goal.

  1. This is someone else's code that I tried out for size and modified:
def browsefunc(): #browse button to search for files
    filename = filedialog.askopenfilename()
    infile = open(filename, 'r')
    content = infile.read()
    pathadd = os.path.dirname(filename)+filename

    pathlabel.delete(0, END)
    pathlabel.insert(0, pathadd)

    return content

Button errors in Tkinter - Selecting files, adding their paths I also did this way, which is a bit different:

def fd_getfile():
    filetypes = (
        ('sys list file', '*.txt'),
        ('any', '*.*')
    )
    filename_file1 = fd.askopenfilename(
        title='add file1',
        initialdir='src',
        filetypes=filetypes)
file1_entry.insert(tk.END, filename_file1)
    showinfo(
        title='file1 selected',
        message=filename_file1,
    )

def process(*args):
    try:
        # COMMENT: Reset output
        file1.set('')

        # COMMENT: Load files
        with open(file1path.get()) as file1:

  1. This is how I got this to work... I haven't seen any example of this online anywhere.
def forkscroll():
    mylabelframe = tk.LabelFrame(myframe, text='My Long Text:').pack()
    scroll_w = 30
    scroll_h = 10
    myscrolledtext = scrolledtext.ScrolledText(mylabelframe, width=scroll_w, height=scroll_h, wrap=tk.WORD)
    myscrolledtext.vbar.config(width=20)
    myscrolledtext.grid(sticky='news', row=6, column=0, rowspan=1, columnspan=1, padx=5, pady=5)

# Open a dialogue; select and load a text file; read the text file directly into the scrolledtext widget (box)
    fork = open(filedialog.askopenfilename(), 'r') # it's the same as "infile" above; but it's not a string
    myscrolledtext.insert(tk.END, fork.read()) ### This reads the content of "fork" into the scrolledtext widget
  1. ...can't do it. As I say, I can run both processes in parallel... browsing twice for files, but each function does something different with what looks like similar code.
  forkit = StringVar()
    forkit.set(fork.get())
    mynormaltext = Text(mylabelframe, width = 10, height = 1, wrap=tk.WORD)
    mynormaltext.grid(sticky='news', row=5, column=0, rowspan=1, columnspan=1, padx=5, pady=5)
    mynormaltext.insert(tk.END, forkit.get())

# Even though it does the same thing in one line as it does in three, the outcome is not the same for scrolledtext
#    forkname = filedialog.askopenfilename()
#    forkfile = open(forkname, 'r')
#    fork = forkfile.read()

# above... "fork" is a textIO, but Text can read it...

I looked at those three lines of forkname, forkfile, and fork, and saw that it looked like a shorthand for fork=open(filedialog.askopenfilename(), 'r').read() and that's how I got the scrolledtext to finally work... but this "fork" is a different filetype in each case... in one it's a string, in another it's a "TextIO" or "FilePath" object. The latter works for scrolledtext, but the former doesn't. The former works for insert to Text, but the latter doesn't. They can't coexist in the same function, and the code doesn't seem to like them in the same .py file, so I guess they should be in separate classes... but I don't know how to convert this code into classes.

Any ideas about how to achieve the intended functionality please?

The intended functionality is:

  1. present 2 labels with 2 buttons each with a field: one as a text widget field; and scrolledtext widget field.
  2. to click a button to browse to a text file, and read it into memory, and print its path into the text widget field
  3. to click the other button, and print the contents of the same file into the scrolledtext field, and have it present within the frame, with a nice long scrollbar.

the closest I can get, so far...


Solution

  • For second part of your question

    The problem with the incomplete path appears because of wrap setting. To solve this just change this string:

    mypathtext = Text(mylabelframe, width=10, height=1)
    

    A feature with backslashes and forward slashes you can fix by using .replace() method.