Я пытаюсь прочитать строку с терминала ubuntu и установить эту строку как метку кнопки. Он отлично работает для некоторой итерации, а затем замерзает или закрывается с ошибкой. Я не мог найти никакого шаблона, когда он зависает или закрывается. Я использую библиотеки gtk и python 2.7.Python GUI зависает или закрывается при попытке обновить текст метки кнопки
Снимок экрана пользовательского интерфейса после его заморозки можно увидеть ниже.
Как видно на рисунке выше, она успешно обновила значение 234, 56, а затем вышел с ошибкой после получения 213 строки. Вы также можете заметить, что кнопка в пользовательском интерфейсе также имеет значение 213.
Иногда пользовательский интерфейс только замерзает, не вызывая никаких ошибок или выхода.
Я использовал следующие коды
1. thread.py (основная программа вызывается из терминала)
import thread
import time
import gui2
import vkeys1
import os
try:
thread.start_new_thread(vkeys1.main, ())
thread.start_new_thread(gui2.main, ())
except:
print "Error: unable to start thread"
# To stop this script from closing
os.system("mkfifo d1 2> error.log")
fd = os.open('d1', os.O_RDONLY)
ch = os.read(fd,1) # No writer
2. vkeys1.py (Она считывает вход от терминала и звонков textinit())
import gui2
def main() :
while True:
try :
gui2.ch = str(input('\nInput a string : '))
gui2.textinit()
except :
print(" \n\n Exception!! \n\n")
3. gui2.py (Обновления надпись на кнопке)
from gi.repository import Gtk, GdkPixbuf, Gdk, GLib
import Image
import os, sys
import time
import vkeys1
import threading
global ch # ch is used at vkeys1.py to store the input
ch = 'dummy content'
button0 = Gtk.Button(label="Initially empty")
class TableWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="String retrieval widget")
self.set_size_request(500,200)
self.connect_after('destroy', self.destroy)
self.main_box=Gtk.VBox()
self.main_box.set_spacing(5)
self.label = Gtk.Label(" ")
table = Gtk.Table(7,4, True)
self.add(self.main_box)
self.main_box.pack_start(self.label, False, False, 0)
self.main_box.pack_start(table, False, False, 0)
table.attach(button0, 0, 4, 0, 1)
self.show_all()
def destroy(window, self):
Gtk.main_quit()
def textinit(): # called from vkeys1.py
class Thrd(threading.Thread) :
def __init__(self) :
threading.Thread.__init__(self)
print('\nReceived string')
print(str(ch))
print('\n')
button0.set_label(str(ch)) # Button label updated here
Thrd2 = Thrd()
Thrd2.start()
return
def main():
app=TableWindow()
app.set_keep_above(True)
app.set_gravity(Gdk.Gravity.SOUTH_WEST)
Gtk.main()
if __name__ == "__main__":# for any error exit
sys.exit(main())
Вышеуказанные коды можно запустить, набрав python thread.py
(после создания этих 3 файлов отклонения от курса). Пожалуйста, предложите любое решение для преодоления этой проблемы с замораживанием.
** Никогда ** не вызывайте функции GTK из потока, отличного от того же потока, который запускает основной цикл. Вместо этого используйте 'GLib.idle_add (...)' для планирования выполнения функции в потоке графического интерфейса. Кроме того, класс 'Thrd' в' gui2' бесполезен, поскольку вы никогда не определяете метод 'run'. – user4815162342
@ user4815162342 Спасибо за ваше предложение. Я попытался добавить 'Glib.idle_add()', но это не сработало. Может быть, я все еще делаю что-то неправильно. Я новичок в python и пользовательском интерфейсе. Можете ли вы отправить измененный код в качестве ответа, чтобы я мог принять ваш ответ. –
У вас были проблемы с вашим примером? Во-первых, вы должны избавиться от универсального обработчика исключений, который просто печатает «Exception !!!!»; его удаление обеспечит фактическую обратную трассировку. (При работе с Python 2 мне приходилось менять 'input' на' raw_input', иначе он поднимался на произвольные строки.) Кроме того, 'vkey1' содержал синтаксические ошибки. Как только я исправил эти ошибки, заменил ненужное создание потока в 'textinit' простым вызовом' button0.set_label (str (ch)) 'и заменил вызов' gui2.textinit() 'на' GLib.idle_add (gui2.textinit) ', ваш пример работал отлично. – user4815162342