Gtk создает новый сокет XEMBED при перемещении сокета из одного ноутбука в другой

Я работаю над приложением с графическим интерфейсом, используя Python 3.7 и PyGTK 3.0. Мой графический интерфейс состоит из нескольких GTK.Notebooks, которые находятся в одной группе, и все их вкладки настроены как съемные. Таким образом, я могу перетащить страницу из одной записной книжки на другую. Это прекрасно работает с большинством виджетов, которые я использую, но я изо всех сил пытаюсь заставить его работать с GTK.Socket. Я хочу запускать внешние программы и показывать их графический интерфейс в виде страницы в одной из записных книжек. Это хорошо работает, но когда я перетаскиваю страницу в другой Блокнот, страница становится пустой.

Я попытался подключиться к сигналам добавления страниц и удаления страниц и вывести на консоль некоторую отладочную информацию. Я заметил, что при каждом перемещении GTK.Socket (перетаскивание в другой блокнот) GTK.Socket получает новый идентификатор. После первого перемещения идентификатор уже отличается от идентификатора, который был у Socket после его создания и добавления. Это заставляет меня задуматься о том, что каждый раз, когда я перемещаю страницу, создается новый сокет, и, очевидно, внешняя программа не принимает к сведению это изменение и продолжает рисовать на старом сокете, который я больше не могу отображать.

Вот MWE для моей проблемы. Он создает окно с двумя записными книжками, установленными в контейнере HPaned. Каждый Блокнот получает TextView в качестве своей первой страницы (поэтому он не пустой), а правильный Блокнот также получает Сокет (который в этом случае относится к сеансу gtkwave). Я также добавил слушателей для добавления страниц и удаления страниц с некоторыми результатами отладки.

import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

def handleAdd(notebook, child, pageNum):
    print("Handle add")
    if isinstance(child, Gtk.Socket):
        print("ID after ADD: " + hex(child.get_id()))

def handleRemove(notebook, child, pageNum):
    print("Handle remove")
    if isinstance(child, Gtk.Socket):
        print("ID after REMOVE: " + hex(child.get_id()))

window = Gtk.Window()

paned = Gtk.HPaned()

notebookLeft = Gtk.Notebook()
notebookRight = Gtk.Notebook()
notebookLeft.connect("page-added", handleAdd)
notebookLeft.connect("page-removed", handleRemove)
notebookRight.connect("page-added", handleAdd)
notebookRight.connect("page-removed", handleRemove)

textviewLeft = Gtk.TextView()
textviewRight = Gtk.TextView()

notebookLeft.append_page(textviewLeft)
notebookLeft.set_tab_detachable(textviewLeft, True)
notebookLeft.set_tab_reorderable(textviewLeft, True)
notebookLeft.set_group_name("Main")
notebookRight.append_page(textviewRight)
notebookRight.set_tab_detachable(textviewRight, True)
notebookRight.set_tab_reorderable(textviewRight, True)
notebookRight.set_group_name("Main")

socket = Gtk.Socket()
notebookRight.append_page(socket)
notebookRight.set_tab_detachable(socket, True)
notebookRight.set_tab_reorderable(socket, True)

paned.add1(notebookLeft)
paned.add2(notebookRight)
window.add(paned)

window.connect("delete-event", Gtk.main_quit)

window.show_all()

print("First socket id " + hex(socket.get_id()))
process = subprocess.Popen(["gtkwave", "/home/benedikt/repos/synpathic/synpathic/testsrc/tb_blake2b.ghw", "-X", hex(socket.get_id())])

Gtk.main()

Если вы запустите код, вы увидите следующие сообщения:

...
ID after ADD: 0x0
(test.py:18825): Gtk-CRITICAL **: 11:42:07.507: gtk_socket_get_id: assertion '_gtk_widget_get_anchored (GTK_WIDGET (socket))' failed
First socket id 0x7400010
... (GTKWave messages) ...

Первый идентификатор - 0x0, потому что сокет еще не был добавлен в окно, это ожидаемое поведение. Это также объясняет ошибку (которая исчезнет, ​​если я не подключу сигнал). Непосредственно перед вызовом Gtk.main() Socket действителен, и ID может быть напечатан. Теперь переместите вкладку с сеансом GTKWave, и вы увидите следующее сообщение для каждого хода:

...
ID after ADD: 0x74001ae
...

Этот идентификатор отличается от первого действительного идентификатора и отличается для каждого хода. Я ожидаю, что этот идентификатор останется прежним, так что внешний GUI все еще может быть показан. Почему создается новый сокет и как я могу обойти эту проблему?

0 ответов

Другие вопросы по тегам