Почему PySimpleGUI с подпроцессом падает на Window7 - PullRequest
1 голос
/ 17 октября 2019

Я новичок в PySimpleGUI. Когда я использую модуль subprocess и упакованный py в exe, он всегда вылетает, как на скриншоте ниже. Но когда я запускаю мой py-файл напрямую в cmd, это просто прекрасно. Так что кто-нибудь подскажите пожалуйста как это исправить? Спасибо.

Exe файл аварийно завершает работу в Windows7 при нажатии ОК: enter image description here

запускать скрипт в CLI при нажатии ОК: enter image description here

SimpleDemoSubprocess Test.py:

import PySimpleGUI as sg
import subprocess


def runCommand(cmd, timeout=None):
    """ run shell command
    @param cmd: command to execute
    @param timeout: timeout for command execution
    @return: (return code from command, command output)
    """

    prt('runCommand, cmd = ' + str(cmd))

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''

    prt('runCommand, communicate')
    out, err = p.communicate()
    prt('runCommand, wait')
    p.wait(timeout)

    prt(out)
    prt(err)
    sg.Popup(out)


    return (out, err)


def prt(self, *args, sep=' ', end='\n', file=None):
    print()
    print(self, *args, sep=' ', end='\r\n', file=None)


# All the stuff inside your window.
layout = [
    [sg.Text('Some text on Row 1')]
    , [sg.Text('Enter something on Row 2'), sg.InputText()]
    , [sg.Button('Ok'), sg.Button('Cancel')]
    # , [sg.PopupScrolled('Hello From PySimpleGUI!', 'This is the shortest GUI program ever!')]
]

# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
    event, values = window.read()
    if event in (None, 'Cancel'):  # if user closes window or clicks cancel
        break
    if event in (None, 'Ok'):  # if user closes window or clicks cancel
        runCommand("ls")
    print('You entered ', values[0])

window.close()

пакет py в exe:

# https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_EXE_Maker.py

import PySimpleGUI as sg
import subprocess
from shutil import copyfile
import shutil
import os

def prt(self, *args, sep=' ', end='\n', file=None):
    print()
    print(self, *args, sep=' ', end='\r\n', file=None)

def Launcher():
    sg.ChangeLookAndFeel('LightGreen')

    layout = [[sg.T('PyInstaller EXE Creator', font='Any 15')],
              [sg.T('Source Python File'), sg.In(key='_sourcefile_', size=(45, 1)),
               sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
              [sg.T('Icon File'), sg.In(key='_iconfile_', size=(45, 1)),
               sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
              [sg.Frame('Output', font='Any 15', layout=[[sg.Output(size=(65, 15), font='Courier 10')]])],
              [sg.ReadFormButton('Make EXE', bind_return_key=True),
               sg.SimpleButton('Quit', button_color=('white', 'firebrick3')), ]]

    window = sg.Window('PySimpleGUI EXE Maker',
                       auto_size_text=False,
                       auto_size_buttons=False,
                       default_element_size=(20, 1,),
                       text_justification='right')

    window.Layout(layout)

    # ---===--- Loop taking in user input --- #
    while True:
        (button, values) = window.Read()
        if button in ('Quit', None):
            break  # exit button clicked

        source_file = values['_sourcefile_']
        icon_file = values['_iconfile_']

        icon_option = '-i "{}"'.format(icon_file) if icon_file else ''
        source_path, source_filename = os.path.split(source_file)
        workpath_option = '--workpath "{}"'.format(source_path)
        dispath_option = '--distpath "{}"'.format(source_path)
        specpath_option = '--specpath "{}"'.format(source_path)
        folder_to_remove = os.path.join(source_path, source_filename[:-3])
        file_to_remove = os.path.join(source_path, source_filename[:-3] + '.spec')
        command_line = 'pyinstaller -wF "{}" {} {} {} {}'.format(source_file, icon_option, workpath_option,
                                                                 dispath_option, specpath_option)

        if button == 'Make EXE':
            try:
                prt('source_file: ' + str(source_file))
                prt('Making EXE... this will take a while.. the program has NOT locked up...')
                window.Refresh()

                prt('window.Refresh')
                window.Refresh()
                prt('Running command: {}'.format(command_line))
                runCommand(command_line)
                shutil.rmtree(folder_to_remove)
                os.remove(file_to_remove)
                prt('**** DONE ****')
            except Exception as e:
                # sg.PopupError('Something went wrong')
                prt("Launcher, Exception = " + e)


def runCommand(cmd, timeout=None):
    """ run shell command
    @param cmd: command to execute
    @param timeout: timeout for command execution
    @return: (return code from command, command output)
    """

    prt('runCommand, cmd = ' + str(cmd))

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''

    prt('runCommand, communicate')
    out, err = p.communicate()
    prt('runCommand, wait')
    p.wait(timeout)

    prt(out)
    prt(err)

    return (out, err)

if __name__ == '__main__':
    Launcher()

1 Ответ

1 голос
/ 18 октября 2019

решается изменением на это:

p = подпроцесс. Открыто (cmd, shell = True, stdout = подпроцесс. PIPE, stderr = подпроцесс. STDOUT, stdin = подпроцесс. PIPE)

...