GoodDumbPerson
GoodDumbPerson

Reputation: 53

How to open a file upon button click PySimpleGui

my goal is to create a button and when the button is pressed to open txt file.

I have already created button in the layout but I can't figure out how to make a txt file open upon button click.

This is python and I'm using PySimpleGui as framework.

The txt file is very long(~600k lines) so ideally it will be in another popup

Couldn't find anything in the documentation nor the cookbook

Upvotes: 2

Views: 8028

Answers (3)

Jason Yang
Jason Yang

Reputation: 13061

To browse a txt file

  • Using sg.FileBrowse to select file and send filename to previous element sg.Input
  • Set option file_types=(("TXT Files", "*.txt"), ("ALL Files", "*.*")) of sg.FileBrowse to filter txt files.

Read txt file by

  • open(filename, 'rt', 'utf-8') as f
  • read all text from f

Create another popup window with element sg.Multiline with text read from txt file.

from pathlib import Path
import PySimpleGUI as sg

def popup_text(filename, text):

    layout = [
        [sg.Multiline(text, size=(80, 25)),],
    ]
    win = sg.Window(filename, layout, modal=True, finalize=True)

    while True:
        event, values = win.read()
        if event == sg.WINDOW_CLOSED:
            break
    win.close()

sg.theme("DarkBlue3")
sg.set_options(font=("Microsoft JhengHei", 16))

layout = [
    [
        sg.Input(key='-INPUT-'),
        sg.FileBrowse(file_types=(("TXT Files", "*.txt"), ("ALL Files", "*.*"))),
        sg.Button("Open"),
    ]
]

window = sg.Window('Title', layout)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event == 'Open':
        filename = values['-INPUT-']
        if Path(filename).is_file():
            try:
                with open(filename, "rt", encoding='utf-8') as f:
                    text = f.read()
                popup_text(filename, text)
            except Exception as e:
                print("Error: ", e)

window.close()

May get problem if txt file with different encoding.

Upvotes: 3

I don't know what is your platform. Anyway, opening a file will involve:

  • choosing a file to be opened (from your formulation, I understand that in your case it's a given file with a known path; otherwise you'd need to use, e.g., sg.FileBrowse()); and
  • executing a command to open the file using a default or a specified reader or editor.

I use the following function (working in MacOS and Windows) to execute a command:

import platform
import shlex
import subprocess

def execute_command(command: str):
    """
    Starts a subprocess to execute the given shell command.
    Uses shlex.split() to split the command into arguments the right way.
    Logs errors/exceptions (if any) and returns the output of the command.

    :param command: Shell command to be executed.
    :type command: str
    :return: Output of the executed command (out as returned by subprocess.Popen()).
    :rtype: str
    """

    proc = None
    out, err = None, None
    try:
        if platform.system().lower() == 'windows':
            command = shlex.split(command)
        proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, 
                                stderr=subprocess.PIPE, text=True)
        out, err = proc.communicate(timeout=20)
    except subprocess.TimeoutExpired:
        if proc:
            proc.kill()
            out, err = proc.communicate()
    except Exception as e:
        if e:
            print(e)
    if err:
        print(err)
    return out

and call it this way to open the file using the default editor:

command = f'\"{filename}\"' if platform.system().lower() == 'windows' else \
   f'open \"{filename}\"'
execute_command(command)

You can tweak command to open the file in an editor of your choice the same way as you would do in CLI.

This is quite a universal solution for various commands. There are shorter solutions for sure :)

Reference: https://docs.python.org/3/library/subprocess.html

Upvotes: 0

Brandon Kauffman
Brandon Kauffman

Reputation: 1865

On linux you have an environment variable called editor like this

EDITOR=/usr/bin/micro

You can get that env using os

file_editor = os.getenv("EDITOR", default = "paht/to/default/editor")

Then you can spawn a process

os.spawnlp(os.P_WAIT, file_editor, '', '/path/to/file')

This essentially be a popup. Windows probably uses a different env name


Leaving the above because this is essentially what this does:

os.system('c:/tmp/sample.txt')

The above snippet is a one liner to do basically what I mentioned above

Upvotes: 0

Related Questions