我开发了一个基于python Gtk3的GUI程序。在主窗口中有一个按钮和一个进度条,我的目的是当按下按钮时有另一个线程运行来做一些工作,最后另一个GTK窗口显示出来显示结果,同时preogress可以更新进度主窗口正确。
但我总是遇到如下错误:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
Aborted (core dumped)
我真的不知道那里出了什么问题并且对此一无所知,是否有人可以帮忙看一下并在这里提供一个例子?
非常感谢!
我在这里开发了一个测试程序,我总是在Linux平台下得到以下错误: (fileChooser.py:40834):Gtk-CRITICAL **:gtk_text_attributes_ref:断言'值!= NULL'失败
(fileChooser.py:40834):Gtk-CRITICAL **:gtk_text_attributes_ref:断言'值!= NULL'失败
(fileChooser.py:40834):Pango-CRITICAL **:pango_layout_new:断言'context!= NULL'失败 分段错误(核心转储)
#!/usr/bin/env python
import os
import re
import multiprocessing
import threading
import platform
from gi.repository import Gtk, GLib, Gdk, GObject
class ANA(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.tree_store = dict()
self.COL_NAME = 0
self.COL_COLOR = 1
self.window = Gtk.Window()
self.window.set_title("Analysing Results")
self.window.set_size_request(1000, 750)
self.connect('destroy', lambda *w: Gtk.main_quit())
self.main_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1)
self.window.add(self.main_vbox)
self.hpaned = Gtk.HPaned()
self.hpaned.set_position(295)
self.main_vbox.pack_start(self.hpaned, True, True, 0)
self.notebook = Gtk.Notebook()
for tab in ['A', 'B']:
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
self._new_notebook_page(self.notebook, scrolled_window, tab)
treeview = self.__create_treeview(tab)
scrolled_window.add(treeview)
self.hpaned.add(self.notebook)
self.notebook1 = Gtk.Notebook()
self.hpaned.add(self.notebook1)
self.scrolled_window2, self.info_buffer, self.info_text_view = self.__create_text(True)
self._new_notebook_page(self.notebook1, self.scrolled_window2, '_Info')
info_text_view = self.info_text_view
self.window.show_all()
def _new_notebook_page(self, notebook, widget, label):
l = Gtk.Label(label='')
l.set_text_with_mnemonic(label)
notebook.append_page(widget, l)
def __create_text(self, is_source=False):
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
text_view = Gtk.TextView()
scrolled_window.add(text_view)
buffer = Gtk.TextBuffer()
text_view.set_buffer(buffer)
text_view.set_editable(False)
text_view.set_cursor_visible(True)
return scrolled_window, buffer, text_view
def __create_treeview(self, tab_name):
treestore = Gtk.TreeStore(str, str)
self.tree_store[tab_name] = treestore
treeview = Gtk.TreeView(treestore)
selection = treeview.get_selection()
selection.set_mode(Gtk.SelectionMode.BROWSE)
treeview.set_size_request(200, -1)
cell = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(tab_name, cell, foreground=self.COL_COLOR)
column.add_attribute(cell, "text", self.COL_NAME)
treeview.append_column(column)
if tab_name == "A":
selection.connect('changed', self.selection_changed_A)
elif tab_name == "B":
selection.connect('changed', self.selection_changed_B)
treeview.expand_all()
return treeview
def selection_changed_A(self):
print "A"
def selection_changed_B(self):
print "B"
class ANALYSING_PROCESS(multiprocessing.Process):
def __init__(self):
super(ANALYSING_PROCESS, self).__init__()
def run(self):
import time
time.sleep(5)
ANA()
class ANALYSING_THREAD(threading.Thread):
def __init__(self, pbar, timer):
super(ANALYSING_THREAD, self).__init__()
self.pbar = pbar
self.timer = timer
def run(self):
Gdk.threads_init()
Gdk.threads_enter()
import time
time.sleep(5)
ANA()
Gdk.threads_leave()
self.pbar.set_text("Done")
self.pbar.set_show_text(True)
GObject.source_remove(self.timer)
class File_Chooser(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect('destroy', lambda *w: Gtk.main_quit())
self.set_title("Test")
self.set_border_width(8)
frame = Gtk.Frame()
self.add(frame)
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
self.vbox.set_border_width(8)
frame.add(self.vbox)
label = Gtk.Label()
label.set_markup("<span font_desc=\"Serif 25\" foreground=\"#015F85\" size=\"x-large\"> Test</span>")
self.vbox.pack_start(label, False, False, 0)
self.button_entry = dict()
self.entry_name = dict()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
button = Gtk.Button("Browse Files")
button.connect('clicked', self.browse_files)
hbox.pack_start(button, False, False, 0)
label = Gtk.Label()
label.set_markup("<span foreground=\"#015F85\"> files </span>")
label.set_use_underline(True)
hbox.pack_start(label, False, False, 0)
self.entry1 = Gtk.Entry()
hbox.pack_start(self.entry1, True, True, 0)
label.set_mnemonic_widget(self.entry1)
self.button_entry[button] = self.entry1
self.entry_name['files'] = self.entry1
self.vbox.pack_start(hbox, False, False, 0)
separator = Gtk.HSeparator()
self.vbox.pack_start(separator, False, False, 1)
alignment1 = Gtk.Alignment()
alignment1.set_halign(Gtk.Align.CENTER)
self.vbox.pack_start(alignment1, False, False, 1)
self.pbar = Gtk.ProgressBar()
alignment1.add(self.pbar)
self.pbar.set_text("Not Run")
self.pbar.set_show_text(True)
hbox2 = Gtk.HBox(False, 2)
self.vbox.pack_start(hbox2, False, False, 1)
button3 = Gtk.Button("Analyze")
button3.connect('clicked', self.tar_File_analyze)
hbox2.pack_end(button3, False, False, 1)
button4 = Gtk.Button("close")
button4.connect('clicked', self.__quit)
hbox2.pack_end(button4, False, False, 1)
self.show_all()
def browse_files(self, button):
dialog = Gtk.FileChooserDialog("Please choose a file", self,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
filter = Gtk.FileFilter()
filter.set_name("Tar files")
filter.add_pattern("*.tar")
filter.add_pattern("*.rar")
filter.add_pattern("*.tar.gz")
dialog.add_filter(filter)
filter = Gtk.FileFilter()
filter.set_name("All files")
filter.add_pattern("*")
dialog.add_filter(filter)
filter = Gtk.FileFilter()
filter.set_name("Images")
filter.add_mime_type("image/png")
filter.add_mime_type("image/jpeg")
filter.add_mime_type("image/gif")
filter.add_pattern("*.png")
filter.add_pattern("*.jpg")
filter.add_pattern("*.gif")
filter.add_pattern("*.tif")
filter.add_pattern("*.xpm")
dialog.add_filter(filter)
response = dialog.run()
if response == Gtk.ResponseType.OK:
print dialog.get_filename(), 'selected'
self.button_entry[button].set_text(dialog.get_filename())
#entry.set_text(dialog.get_filename())
elif response == Gtk.ResponseType.CANCEL:
print 'Closed, no files selected'
dialog.destroy()
def tar_File_analyze(self, button):
#PROGRESS_THREAD(self.pbar).start()
self.pbar.set_text("Running")
self.pbar.set_show_text(True)
####self.timer = GObject.timeout_add (100, self.progress_timeout, self)
self.timer = GLib.timeout_add(100, self.progress_timeout)
t = ANALYSING_THREAD(self.pbar, self.timer)
#t = ANALYSING_PROCESS()
t.start()
def progress_timeout(self):
self.pbar.pulse()
return True
def warning(self, warnings):
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.WARNING,
Gtk.ButtonsType.OK, "Warning!")
dialog.format_secondary_text(warnings)
response = dialog.run()
if response == Gtk.ResponseType.OK:
dialog.destroy()
def __quit(self, button):
self.destroy()
def run(self):
Gtk.main()
def main():
File_Chooser().run()
if __name__ == '__main__':
main()
有人可以看一下吗?
答案 0 :(得分:1)
通常,GUI工具包不支持多个线程进行工具包调用。通常只允许初始线程这样做。使GUI工具包真正是线程安全的是一个难题,这是一种避免它的方法。
一种可能的解决方案是让主线程使用空闲函数或计时器回调来检查工作线程中的进度。
另一个解决方案是使用外部进程而不是线程进行工作。这有许多优点;