Python 2.7 — 3.7 tkinter scrolledtext не работает

#python #tkinter #python-2to3

#python #tkinter #python-2to3

Вопрос:

У меня есть графический интерфейс Python 2.7, использующий Tkinter и переносящий его на 3.7. Он передает стандартный вывод подпроцесса в виджет scrolledtext и отлично работает с 2.7, но с 3.7 он постоянно обновляет виджет, и я не могу прокручивать. Фрагмент кода:

 #lauch main
    proc = subprocess.Popen(["python", testPath, filePath]   script_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=0)

    #clear the text box widget
    text.delete("1.0", END)

    #check for alternate main.py
    if (alt_main_flag == True):
        text.insert(END, "Using alternate MAIN script in "   filePath   'n')

    #send the scripts output to the GUI text box
    # for 3.x, had to use bytes() conversion prior to 'in'
    for line in iter(proc.stdout.readline,''):
        if (bytes("Starting ", 'ascii') in line):
            line = line.strip()
            statusvar.set(line)
        else:
            text.insert(END, line)
        if (bytes("end of program", 'ascii') in line):
            statusvar.set("Ready")
        #update in "real time"
        text.see(END)
        root.update()
        text.update_idletasks()
  

Предложения?

Отметить

Комментарии:

1. Когда я удаляю строку text.see (END), все становится «лучше»… Я могу прокручивать, когда подпроцесс завершается… но, конечно, текст не обновляется / не прокручивается в «реальном времени»… он остается наверху. Должен быть лучший способ!

2. Заметил, что когда я отключаю графический интерфейс, python выдает эту ошибку: File «Z:ProjectsPython_Test_ScriptsGui_Test3_8_GUIGUI_2.py «, строка 675, в файле startMain text.update_idletasks() «C:Python37libtkinter_init_.py «, строка 1182, в update_idletasks self.tk.call(‘update’, ‘idletasks’) _tkinter. TclError: не удается вызвать команду «обновить»: приложение было уничтожено — как будто цикл for все еще выполняется! ПОЧЕМУ??? Это объяснило бы все, что я вижу.

3. Это ИМЕННО то, что не так! Цикл for никогда не завершается. Что за черт?

Ответ №1:

Найден обходной путь: добавлен разрыв в цикл for.

 for line in iter(proc.stdout.readline,''):
        if (bytes("Starting ", 'ascii') in line):
            line = line.strip()
            statusvar.set(line)
        else:
            text.insert(END, line)
        if (bytes("end of program", 'ascii') in line):
            statusvar.set("Ready")
        if (len(line) == 0):
            break
            
        #update in "real time"
        text.see(END)
        root.update()
        text.update_idletasks()
  

Комментарии:

1. Вы можете установить text=True subprocess.Popen(...) , тогда вам не нужно использовать bytes(...) . Также вы можете просто использовать for line in proc.stdout: вместо этого. И вам не нужно вызывать root.update() .