В Qt4 мы могли бы использовать embedInto
метод QX11EmbedWidget
класс для встраивания любого QWidget
в другое приложение. Но в Qt5 QX11EmbedWidget
класс был исключен. Я искал в Google много часов, но все, что я нашел, указывало на использование QWidget::createWindowContainer
метод вместо. Однако, насколько я понимаю, этот метод является скорее заменой QX11EmbedContainer
,
Итак, вот вопрос: Как мы встраиваем Qt5-Widget в не-Qt окно? —
И в случае, если это встречается: Окно не Qt — Gtk3.
Меня попросили использование регистра, Итак, позвольте мне кратко проиллюстрировать: Рассмотрим приложение на основе Gtk, которое вы хотите расширить — и необходимый вам компонент UI уже существует, но написан на Qt. Цель состоит в том, чтобы избежать портирования приложения на Qt или компонента на Gtk.
Мой первоначальный подход состоял в том, чтобы запросить встраивание со стороны Qt. Мне не повезло с этим, так как я не мог найти эквивалент для QX11EmbedWidget::embedInto
в Qt5. Отказавшись от этого, я решил дать XReparentWindow
попытка, которая была по сообщениям использовался с успехом. Однако из-за отсутствия документации я не смог воспроизвести это. Моя третья попытка состояла в том, чтобы начать сервер сторона, которая является окном Gtk в моем случае. Я рад сообщить, что это сработало 🙂
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();
}
Надеюсь, это может сэкономить кому-то много часов.
Цитировать по этой ссылке:
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