Multithreading 在GUI线程外部调用QAxWidget方法
我开始怀疑这是否是不可能的,但我想我会问一下,以防有一个聪明的方法来解决我遇到的问题 我有一个使用ActiveX控件的Qt应用程序。该控件由QAxWidget持有,QAxWidget本身包含在另一个QWidget中(我需要向该小部件添加额外的信号/插槽,我不能只是将QAxWidget子类化,因为该类不允许这样做)。当我需要与ActiveX控件交互时,我调用QWidget的一个方法,该方法反过来调用QAxWidget的dynamicCall方法,以便调用ActiveX控件的相应方法。所有这些都很好 但是,ActiveX控件的一个方法需要几秒钟才能返回。当我调用这个方法时,我的整个GUI会锁定几秒钟,直到该方法返回。这是不可取的。我希望ActiveX控件自行关闭并进行处理,并在完成后返回给我,而不锁定Qt GUI 我尝试了几件事,但都没有成功:Multithreading 在GUI线程外部调用QAxWidget方法,multithreading,qt,activex,Multithreading,Qt,Activex,我开始怀疑这是否是不可能的,但我想我会问一下,以防有一个聪明的方法来解决我遇到的问题 我有一个使用ActiveX控件的Qt应用程序。该控件由QAxWidget持有,QAxWidget本身包含在另一个QWidget中(我需要向该小部件添加额外的信号/插槽,我不能只是将QAxWidget子类化,因为该类不允许这样做)。当我需要与ActiveX控件交互时,我调用QWidget的一个方法,该方法反过来调用QAxWidget的dynamicCall方法,以便调用ActiveX控件的相应方法。所有这些都很好
- 创建新的QThread并从新线程调用QAxWidget::dynamicCall
- 将信号连接到QAxWidget的适当插槽方法,并使用信号/插槽而不是使用dynamicCall调用该方法
- 使用QtConcurrent::run调用QAxWidget::dynamicCall
是否有任何方法可以将此ActiveX处理与QtGUI线程分离,以便在ActiveX控件运行方法时GUI不会锁定?使用QAxBase或QAxObject有什么聪明的方法可以得到我想要的结果吗?经过一些实验后,我通过做一些我认为我以前尝试过的事情来解决这个问题:创建一个新的QThread并从新线程调用QAxWidget::dynamicCall。我第一次尝试这个解决方案时一定没有正确编码;在和一位同事坐在一起之后,我们能够让它工作起来。具体来说,我们所做的是: (步骤1)创建了QThread的子类来表示需要调用dynamicCall()的线程 (步骤2)在QThread的构造函数中,传入指向原始QAxWidget的指针,并将指针保留在成员变量中
MyThread::MyThread(QAxWidget* passedWidget) : QThread()
{
actualWidget = passedWidget;
}
(步骤3)在QThread的run()方法中,调用QAxWidget的dynamicCall()方法
void MyThread::run()
{
QVariant result = actualWidget->dynamicCall(...parms as necessary...);
}
(步骤4)回到我的主代码中,当我需要执行dynamicCall()时,我只调用MyThread的start()方法。start()方法将在自己的线程中执行run(),从而向ActiveX对象发送必要的命令,而不会阻塞或暂停GUI主线程。经过一些实验,我可以通过做一些我认为我以前尝试过的事情来解决这个问题:创建一个新的QThread并从新线程调用QAxWidget::dynamicCall。我第一次尝试这个解决方案时一定没有正确编码;在和一位同事坐在一起之后,我们能够让它工作起来。具体来说,我们所做的是: (步骤1)创建了QThread的子类来表示需要调用dynamicCall()的线程 (步骤2)在QThread的构造函数中,传入指向原始QAxWidget的指针,并将指针保留在成员变量中
MyThread::MyThread(QAxWidget* passedWidget) : QThread()
{
actualWidget = passedWidget;
}
(步骤3)在QThread的run()方法中,调用QAxWidget的dynamicCall()方法
void MyThread::run()
{
QVariant result = actualWidget->dynamicCall(...parms as necessary...);
}
(步骤4)回到我的主代码中,当我需要执行dynamicCall()时,我只调用MyThread的start()方法。start()方法将在其自己的线程中执行run(),从而向ActiveX对象发送必要的命令,而不会阻塞或暂停主GUI线程。如果不需要事件循环,则无需将QThread子类化!我认为这是解决这个问题的方法,而不需要向拥有QAxWidget的主线程发送大量信号。引用QThread的Qt5.3的最新文档也证明了这一点。如果不需要事件循环,那么就没有必要不将QThread子类化!我认为这是解决这个问题的方法,而不需要向拥有QAxWidget的主线程发送大量信号。Qt 5.3的最新文档引用了QThread,也证明了这一点。我将不再引用这篇文章:展示使用QThread的另一种方法。您可能已经能够将
QWidget
或QAxWidget
移动到一个线程,并进行调用,而不是不必要地对QThread
进行子类化。您可能已经能够将QWidget
或QAxWidget
移动到线程并进行调用,而不是对QThread
进行不必要的子类化。