首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >QX11EmbedWidget在Qt5中的对应部分是什么?

QX11EmbedWidget在Qt5中的对应部分是什么?
EN

Stack Overflow用户
提问于 2016-08-05 21:54:12
回答 2查看 1.6K关注 0票数 3

在Qt4中,我们可以使用QX11EmbedWidget类的embedInto方法将任何QWidget嵌入到另一个应用程序中。但是在Qt5中,QX11EmbedWidget类被删除了。我已经搜索谷歌很多个小时了,但我发现的都是用QWidget::createWindowContainer方法代替的。然而,据我所知,这个方法相当地替代了QX11EmbedContainer

所以问题是:,我们如何将Qt5-Widget嵌入到一个非Qt窗口中?-如果它是metters:非Qt窗口是Gtk3。

有人要求我使用用例,所以让我简单地说明一下:考虑一个基于Gtk的应用程序,您愿意扩展它,并且您需要的UI组件已经存在,但是是用Qt编写的。目的是避免将应用程序移植到Qt或组件到Gtk。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-06 00:15:01

我最初的方法是请求从Qt侧嵌入。我在这方面没有任何进展,因为我在Qt5中找不到任何类似的Qt5。在放弃这一点之后,我决定给XReparentWindow一个尝试,那就是据说成功地使用了。然而,由于缺乏文档,我无法复制这个。我的第三次尝试是从服务器端启动嵌入,在我的例子中,服务器端就是Gtk窗口。我很高兴地报告,它起了作用:-)

记录:如何将任意Qt5 Widget嵌入到Gtk窗口中

TL;DR:

  1. 确保将Gtk代码编写在与Qt部分分离的单元中。为了避免Qt5和Gtk3之间的名称冲突,这是必要的。
  2. 只需使用gtk_socket_add_id将任何X11窗口嵌入到GtkSocket中即可。

请参阅文献资料以获得参考,但请注意,给出的示例甚至没有编译,因为它们忘记了GTK_SOCKET宏。相反,下面的代码可以工作。

详细信息

QGtkWindow类为Gtk窗口提供了一个接口。

代码语言:javascript
运行
复制
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窗口。

代码语言:javascript
运行
复制
class GtkWindowAdapter
{

public:

    GtkWindowAdapter();
    ~GtkWindowAdapter();

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

private:

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

}; // GtkWindowAdapter

实例化时,GtkWindowAdapter对象首先初始化Gtk,

代码语言:javascript
运行
复制
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窗口:

代码语言:javascript
运行
复制
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窗口变为可见的。

代码语言:javascript
运行
复制
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放入该窗口:

代码语言:javascript
运行
复制
QGtkWindow::QGtkWindow()
    : container( new QWidget() )
{
    container->setLayout( new QVBoxLayout() );
    gtkWindow.embed( container->winId() );
    container->show();
}

QGtkWindow类的用户决定将一些小部件放入窗口时,setCentralWidget就是最好的选择。它只是清除原来嵌入到Gtk窗口中的父小部件,然后插入用户的小部件:

代码语言:javascript
运行
复制
void QGtkWindow::setCentralWidget( QWidget* const widget )
{
    qDeleteAll( pimpl->container->layout()->children() );
    pimpl->container->layout()->addWidget( widget );
}

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

希望这能给别人留几个小时。

票数 3
EN

Stack Overflow用户

发布于 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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38798252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档