Ich versuche, eine Zeichenfolge aus dem Ubuntu-Terminal zu lesen und diese Zeichenfolge als Beschriftung einer Schaltfläche festzulegen. Es funktioniert perfekt für einige Iteration und dann friert oder schließt mit Fehler. Ich konnte kein Muster finden, wenn es gefriert oder schließt. Ich benutze gtk Bibliotheken und Python 2.7.Python GUI friert ein oder wird geschlossen, während versucht wird, den Button-Label-Text zu aktualisieren
Ein Screenshot der Benutzeroberfläche, nachdem es eingefroren ist, kann unten gesehen werden.
Wie in der obigen Screenshot sehen ist, hat sie erfolgreich den Wert 234, 56 aktualisiert, und verließ dann mit Fehlern nach 213 Zeichenfolge empfängt. Sie können auch beobachten, dass die Schaltfläche in der Benutzeroberfläche ebenfalls 213 hat.
Manchmal erstarrt die Benutzeroberfläche, ohne dass Fehler angezeigt oder beendet werden.
ich verwendet habe, die folgenden Codes
1. thread.py (Hauptprogramm von Terminal genannt)
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 (Er liest den Eingang von Terminal und Anrufe 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 (Aktualisiert das Button-Beschriftung)
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())
Die obigen Codes können durch Eingabe von python thread.py
ausgeführt werden (nach den oben genannten drei Dateien off-Kurs erstellen). Bitte schlagen Sie eine Lösung vor, um dieses Gefrierproblem zu lösen.
** Niemals ** GTK-Funktionen von einem anderen Thread als dem Thread aufrufen, der die Hauptschleife ausführt. Verwenden Sie stattdessen 'GLib.idle_add (...)', um die Ausführung der Funktion im GUI-Thread zu planen. Außerdem ist die 'Thrd'-Klasse in' gui2' nutzlos, da Sie niemals die 'run'-Methode definieren. – user4815162342
@ user4815162342 Vielen Dank für Ihren Vorschlag. Ich habe versucht, 'Glib.idle_add()' hinzuzufügen, aber es hat nicht funktioniert. Vielleicht mache ich immer noch etwas falsch. Ich bin neu in Python und UI. Können Sie den geänderten Code bitte als Antwort posten, damit ich Ihre Antwort annehmen kann. –
Haben Sie andere Probleme mit Ihrem Beispiel behoben? Zuerst sollten Sie den generischen Exception-Handler loswerden, der nur "Exception !!!!" ausgibt; Entfernen wird das tatsächliche Backtrace bereitstellen. (Wenn ich mit Python 2 arbeite, musste ich 'input' in' raw_input' ändern, ansonsten in willkürlichen Strings.) Auch 'vkey1' enthielt Syntaxfehler. Nachdem ich diese Fehler behoben hatte, ersetzte ich die unnötige Thread-Erstellung in 'textinit' durch einen einfachen Aufruf von' button0.set_label (str (ch)) 'und ersetzte den Aufruf durch 'GLib.idle_add() in gui2.textinit()'. gui2.textinit) ', Ihr Beispiel hat gut funktioniert. – user4815162342