在Qt4中,我们可以使用QX11EmbedWidget类的embedInto方法将任何QWidget嵌入到另一个应用程序中。但是在Qt5中,QX11EmbedWidget类被删除了。我已经搜索谷歌很多个小时了,但我发现的都是用QWidget::createWindowContainer方法代替的。然而,据我所知,这个方法相当地替代了QX11EmbedContainer。
所以问题是:,我们如何将Qt5-Widget嵌入到一个非Qt窗口中?-如果它是metters:非Qt窗口是Gtk3。
有人要求我使用用例,所以让我简单地说明一下:考虑一个基于Gtk的应用程序,您愿意扩展它,并且您需要的UI组件已经存在,但是是用Qt编写的。目的是避免将应用程序移植到Qt或组件到Gtk。
发布于 2016-08-06 00:15:01
我最初的方法是请求从Qt侧嵌入。我在这方面没有任何进展,因为我在Qt5中找不到任何类似的Qt5。在放弃这一点之后,我决定给XReparentWindow一个尝试,那就是据说成功地使用了。然而,由于缺乏文档,我无法复制这个。我的第三次尝试是从服务器端启动嵌入,在我的例子中,服务器端就是Gtk窗口。我很高兴地报告,它起了作用:-)
记录:如何将任意Qt5 Widget嵌入到Gtk窗口中
TL;DR:
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;
}; // QGtkWindowGtkWindowAdapter类封装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初始化一个Gtk窗口,并将一个空的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();
}希望这能给别人留几个小时。
发布于 2016-08-05 21:59:43
引用此链接:
https://forum.qt.io/topic/32785/qwindow-qwidget-qt5-x11embedding-how/2 所有的x11的东西已经转移到“额外的”部门,发现在吉特立德。(QX11EmbedWidgets和QX11EmbedContainer等人不在5.x中)
试试这个:
http://qt-project.org/doc/qt-5.1/qtx11extras/qx11info.html
https://stackoverflow.com/questions/38798252
复制相似问题