Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GUI在尝试更新按钮标签文本时冻结或关闭_Python_User Interface_Gtk_Pygtk_Freeze - Fatal编程技术网

Python GUI在尝试更新按钮标签文本时冻结或关闭

Python GUI在尝试更新按钮标签文本时冻结或关闭,python,user-interface,gtk,pygtk,freeze,Python,User Interface,Gtk,Pygtk,Freeze,我试图从ubuntu终端读取一个字符串,并将该字符串设置为按钮的标签。它在某些迭代中工作得很好,然后冻结或错误关闭。我找不到任何关于它何时冻结或关闭的模式。我正在使用gtk库和python 2.7 用户界面冻结后的屏幕截图如下所示 如上面的屏幕截图所示,它成功地更新了值234、56,然后在收到213字符串后出错退出。您还可以观察到UI中的按钮也有213值 有时UI只是冻结,没有显示任何错误或退出 我使用了以下代码 一,。thread.py(从终端调用的主程序) 二,。vkeys1.py(它从终

我试图从ubuntu终端读取一个字符串,并将该字符串设置为按钮的标签。它在某些迭代中工作得很好,然后冻结或错误关闭。我找不到任何关于它何时冻结或关闭的模式。我正在使用gtk库和python 2.7

用户界面冻结后的屏幕截图如下所示

如上面的屏幕截图所示,它成功地更新了值234、56,然后在收到213字符串后出错退出。您还可以观察到UI中的按钮也有213值

有时UI只是冻结,没有显示任何错误或退出

我使用了以下代码

一,。thread.py(从终端调用的主程序)

二,。vkeys1.py(它从终端读取输入并调用textinit())

三,。gui2.py(更新按钮标签)


通过键入
python-thread.py
(在创建上述3个文件之后)可以运行上述代码。请建议解决此冻结问题的任何解决方案。

崩溃的最可能原因是您的代码从运行主循环的线程以外的线程调用GTK代码,这是不允许的

要解决此问题,请将调用
gui2.textinit()
替换为
GLib.idle\u add(gui2.textinit)
(注意
textinit
后面缺少括号)

关于守则的几点意见:

  • 通用异常处理程序正在屏蔽发生的异常。删除它,当出现问题时,您将看到有用的回溯

  • 如果您在Python2下运行,您可能希望将
    input
    更改为
    raw\u input
    ,否则代码会阻塞任何不是有效Python表达式的输入

  • textinit
    创建一个从不运行实际线程的线程对象。从
    threading.Thread
    继承时,必须重写
    run
    函数,调用
    start()
    后将在新线程中调用该函数。在构造器中执行此工作将一事无成

  • thread.start\u new\u thread
    是一种低级API,在正常情况下不应使用,在Python 3中降级为
    \u thread
    。不要使用
    thread.start\u new\u thread(fn,())
    ,而是使用
    threading.thread(target=fn)
    ,它具有相同的含义,并且还返回一个
    thread
    对象


切勿从运行主循环的同一线程以外的线程调用GTK函数。相反,使用GLib.idle\u add(…)来计划GUI线程中函数的执行。另外,
gui2
中的
Thrd
类是无用的,因为您从未定义
run
方法。@user4815162342谢谢您的建议。我试图添加Glib.idle\u add(),但没有成功。也许,我还是做错了什么。我不熟悉python和UI。你能把修改后的代码作为答案贴出来吗?这样我就可以接受你的答案了。你用你的例子解决了其他问题了吗?首先,您应该去掉只打印“exception!!!!”的通用异常处理程序;删除它将提供实际的回溯。(在使用Python 2运行时,我必须将
input
更改为
raw_input
,否则它会在任意字符串上引发。)此外,
vkey1
包含语法错误。一旦我修复了这些错误,就用对
button0.set_label(str(ch))
的简单调用替换了
textinit
中不必要的线程创建,并用
GLib.idle\u add(gui2.textinit)
替换了对
gui2.textinit()
的调用,您的示例运行得很好。@user4815162342谢谢您。它至少可以运行30次迭代。有没有办法不用GLib.idle\u add()调用
gui2.textinit()
?实际上,现在我添加了一些额外的代码,现在它不调用
gui2.textinit()
,因为它不是空闲的。问题是我需要立即调用
gui2.textinit()
。@user4815162342抱歉。由于道德原因,我不能在这里发布额外的代码。请告诉我是否有任何方法可以立即调用该函数(即不使用空闲函数)。提前谢谢。
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
import gui2
def main() :
    while True:
        try :           
            gui2.ch = str(input('\nInput a string :   '))
            gui2.textinit()
        except :
            print(" \n\n Exception!! \n\n")
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())