Qt ActiveX控件,QWindow的QWidget容器放入QScrollArea中出现异常

问题描述:

为了支持在网页中播放实时视频,使用Qt做网页插件,用第三方渲染器(D3D)来渲染视频。采用如下方法:

m_window = new QWindow;
m_subWidget = createWindowContainer(m_window, this);
PLAY_Play(m_testPort, (HWND)m_window->winId());

"(HWND)m_window->winId()"可以获取到窗口句柄传给第三方渲染器(D3D)用于渲染视频,而createWindowContainer是作为QWindow的容器可以用于界面布局。当此容器或者与该容器有的父窗口被放入到QScrollArea中,发现页面中所有的控件都变成了Qt::WA_NativeWindow属性,界面布局错乱、下拉框发生偏移,如下:

问题定位

问题定位许久未找到线索(希望有大神能够指点一下,不胜感激),所以决定弃用QScrollArea,此前之所以使用QScrollArea是因为浏览器的滚动条不会自动刷新,比如当切换QStackedWidget页面时,界面的宽高会发生改变,可能超出浏览器活动区域的宽高,而此时浏览器却不会自动出现滚动条,需要人为地调整一下浏览器的宽高,滚动条才会出现。查阅资料得知,当浏览器的窗口发生改变时,会重排整个页面,所以会出现滚动条。所以目前的问题解决方向是:在Qt切换页面时,需要通知浏览器去重排页面,如何使Qt ActiveX插件与浏览器交互是该问题的关键。

查阅资料后得知,Qt的对象中定义如下信号:

signals:
     void eventCallBack(int nType, QString strEventName);

在点击按钮,切换页面时,发送该信号:

void ActiveQtSurveillance::buttonClicked()
{
    ...
    emit eventCallBack(1000, "hello world!\n");
}

然后在html中加入函数eventCallBack,如下

<html>
<head>
<title>IPC Demo</title>

<body>
<object id="qtActivex" width="100%" height="100%"
classid="clsid:c3538267-2075-48eb-b623-fb1f7e831132">
</object>
</body>

<script>
var g_temp = 1;

function qtActivex::eventCallBack(nType, strEventName)
{
	var ele = document.getElementById('qtActivex');
	var winWidth = document.body.clientWidth;
	if (g_temp) {
		g_temp = 0;
		ele.style.width = "99.9%";
	} else {
		g_temp = 1;
		ele.style.width = "99.8%";
	}
} 
</script>

</html>

当Qt发送信号时,JavaScript就会响应qtActivex::eventCallBack函数,该函数的作用是微调浏览器的客户区大小以实现窗口重排(因为不懂javascript,不知道如何可以直接让浏览器重排,所以用这样的办法来替代)。

经测试,程序运行正常。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当我们开发Qt应用程序时,可以使用QtActiveQt框架将Qt控件转换成ActiveX控件,让它们支持在Windows平台上以COM对象的形式被其他应用程序调用。 具体实现步骤如下: 1. 在Qt Creator创建一个新的Qt Widget工程。 2. 在工程添加Qt控件,例如QPushButton、QLabel等。 3. 在Qt Creator打开.pro文件,添加如下代码: ```qmake CONFIG += qt warn_on QT += core gui activeqt greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = MyActiveX TEMPLATE = lib DEFINES += MYACTIVEX_LIBRARY SOURCES += myactivex.cpp \ widget.cpp HEADERS += myactivex.h \ widget.h FORMS += widget.ui RESOURCES += \ resources.qrc ``` 这里我们可以看到,除了添加了activeqt配置项外,还需要将TARGET设置为MyActiveX,并将TEMPLATE设置为lib,表示生成的是一个动态链接库。 4. 在widget.h头文件,将控件类继承自QAxWidget类,并添加Q_OBJECT宏: ```cpp class Widget : public QAxWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); }; ``` 这里需要注意,使用QAxWidget作为基类之后,我们需要在类的构造函数调用setControl()函数来指定ActiveX控件的CLSID。 5. 在widget.cpp文件,实现控件类的构造函数和析构函数: ```cpp Widget::Widget(QWidget *parent) : QAxWidget(parent) { setControl("QAxTestLib.TestWidget"); } Widget::~Widget() { } ``` 这里我们调用setControl()函数指定了ActiveX控件的名称。 6. 在.pro文件添加QAxContainer模块,并重新编译程序: ```qmake QT += core gui activeqt axcontainer ``` 7. 在Qt Creator的“项目”菜单选择“生成MyActiveX”,即可生成一个ActiveX控件的DLL文件。 通过以上步骤,我们就可以将Qt控件转换成ActiveX控件,并生成一个支持COM对象的DLL文件。需要注意的是,在将ActiveX控件嵌入到其他应用程序使用时,还需要进行一些额外的配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值