Что является аналогом QX11EmbedWidget в Qt5?

В Qt4 мы могли бы использовать embedInto метод QX11EmbedWidget класс для встраивания любого QWidget в другое приложение. Но в Qt5 QX11EmbedWidget класс был исключен. Я искал в Google много часов, но все, что я нашел, указывало на использование QWidget::createWindowContainer метод вместо. Однако, насколько я понимаю, этот метод является скорее заменой QX11EmbedContainer,

Итак, вот вопрос: Как мы встраиваем Qt5-Widget в не-Qt окно?
И в случае, если это встречается: Окно не Qt — Gtk3.


Меня попросили использование регистра, Итак, позвольте мне кратко проиллюстрировать: Рассмотрим приложение на основе Gtk, которое вы хотите расширить — и необходимый вам компонент UI уже существует, но написан на Qt. Цель состоит в том, чтобы избежать портирования приложения на Qt или компонента на Gtk.

3

Решение

Мой первоначальный подход состоял в том, чтобы запросить встраивание со стороны Qt. Мне не повезло с этим, так как я не мог найти эквивалент для QX11EmbedWidget::embedInto в Qt5. Отказавшись от этого, я решил дать XReparentWindow попытка, которая была по сообщениям использовался с успехом. Однако из-за отсутствия документации я не смог воспроизвести это. Моя третья попытка состояла в том, чтобы начать сервер сторона, которая является окном Gtk в моем случае. Я рад сообщить, что это сработало 🙂


Для записи: Как встроить произвольный виджет Qt5 в окно Gtk

TL; DR:

  1. Убедитесь, что вы пишете свой код Gtk в модуле, отдельном от части Qt. Это необходимо для того, чтобы избежать конфликтов имен между Qt5 и Gtk3.
  2. Просто использовать gtk_socket_add_id встроить любое окно X11 в GtkSocket,

Также см документация для справки, но учтите, что данный пример даже не компилируется, потому что они забыли GTK_SOCKET макро. Напротив, следующий код работает.

доказательство

подробности

QGtkWindow Класс предоставляет интерфейс к окну Gtk.

class QGtkWindow : public QObject
{

public:

QGtkWindow();
virtual ~QGtkWindow();

void setCentralWidget( QWidget* const widget );
void show();

private:

GtkWindowAdapter gtkWindow;
QWidget* const container;

}; // QGtkWindow

GtkWindowAdapter Класс оборачивает вызовы Gtk и изолирует их от части приложения Qt. Объект этого класса представляет окно Gtk.

class GtkWindowAdapter
{

public:

GtkWindowAdapter();
~GtkWindowAdapter();

void show();
void embed( unsigned long clientWinId );

private:

struct Details;
const std::auto_ptr< Details > pimpl;

}; // GtkWindowAdapter

Когда создается экземпляр GtkWindowAdapter объект сначала инициализирует Gtk,

static bool gtkInitialized = false;

struct GtkWindowAdapter::Details
{
GtkWidget* widget;
GtkWidget* socket;

void setupUi();
};

GtkWindowAdapter::GtkWindowAdapter()
: pimpl( new Details() )
{
if( !gtkInitialized )
{
int argc = 0;
gtk_init( &argc, NULL );
gtkInitialized = true;
}
pimpl->setupUi();
}

и затем настраивает окно Gtk:

void GtkWindowAdapter::Details::setupUi()
{
widget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
socket = gtk_socket_new();
gtk_widget_show( socket );
gtk_container_add( GTK_CONTAINER ( widget ), socket );
gtk_widget_realize( socket );
}

Вы, возможно, уже отметили embed метод, который обеспечивает этот класс. Этот метод инициирует встраивание любого окна X11. show метод превращает инкапсулированное окно Gtk видимым.

void GtkWindowAdapter::embed( unsigned long clientWinId )
{
gtk_socket_add_id( GTK_SOCKET( pimpl->socket ), clientWinId );
}

void GtkWindowAdapter::show()
{
gtk_widget_show( pimpl->widget );
}

Теперь реализация QGtkWindow класс довольно прост. После создания он инициализирует окно Gtk, используя GtkWindowApdater и кладет пустой QWidget в это окно:

QGtkWindow::QGtkWindow()
: container( new QWidget() )
{
container->setLayout( new QVBoxLayout() );
gtkWindow.embed( container->winId() );
container->show();
}

Когда пользователь QGtkWindow класс решает поместить некоторый виджет в окно, setCentralWidget это путь Он просто очищает родительский виджет, который изначально был встроен в окно Gtk, а затем вставляет вместо него виджет пользователя:

void QGtkWindow::setCentralWidget( QWidget* const widget )
{
qDeleteAll( pimpl->container->layout()->children() );
pimpl->container->layout()->addWidget( widget );
}

void QGtkWindow::show()
{
pimpl->gtkWindow.show();
}

Надеюсь, это может сэкономить кому-то много часов.

3

Другие решения

Цитировать по этой ссылке:

https://forum.qt.io/topic/32785/qwindow-qwidget-qt5-x11embedding-how/2

Все материалы по x11 были перенесены в отдел дополнительных услуг, который можно найти на
Gitorious. (QX11EmbedWidgets и QX11EmbedContainer и тому подобное
не в 5.х)

Попробуй это:

http://qt-project.org/doc/qt-5.1/qtx11extras/qx11info.html

1

По вопросам рекламы [email protected]