Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在GUI线程外部调用QAxWidget方法_Multithreading_Qt_Activex - Fatal编程技术网

Multithreading 在GUI线程外部调用QAxWidget方法

Multithreading 在GUI线程外部调用QAxWidget方法,multithreading,qt,activex,Multithreading,Qt,Activex,我开始怀疑这是否是不可能的,但我想我会问一下,以防有一个聪明的方法来解决我遇到的问题 我有一个使用ActiveX控件的Qt应用程序。该控件由QAxWidget持有,QAxWidget本身包含在另一个QWidget中(我需要向该小部件添加额外的信号/插槽,我不能只是将QAxWidget子类化,因为该类不允许这样做)。当我需要与ActiveX控件交互时,我调用QWidget的一个方法,该方法反过来调用QAxWidget的dynamicCall方法,以便调用ActiveX控件的相应方法。所有这些都很好

我开始怀疑这是否是不可能的,但我想我会问一下,以防有一个聪明的方法来解决我遇到的问题

我有一个使用ActiveX控件的Qt应用程序。该控件由QAxWidget持有,QAxWidget本身包含在另一个QWidget中(我需要向该小部件添加额外的信号/插槽,我不能只是将QAxWidget子类化,因为该类不允许这样做)。当我需要与ActiveX控件交互时,我调用QWidget的一个方法,该方法反过来调用QAxWidget的dynamicCall方法,以便调用ActiveX控件的相应方法。所有这些都很好

但是,ActiveX控件的一个方法需要几秒钟才能返回。当我调用这个方法时,我的整个GUI会锁定几秒钟,直到该方法返回。这是不可取的。我希望ActiveX控件自行关闭并进行处理,并在完成后返回给我,而不锁定Qt GUI

我尝试了几件事,但都没有成功:

  • 创建新的QThread并从新线程调用QAxWidget::dynamicCall
  • 将信号连接到QAxWidget的适当插槽方法,并使用信号/插槽而不是使用dynamicCall调用该方法
  • 使用QtConcurrent::run调用QAxWidget::dynamicCall
似乎没有什么会影响这种行为。无论我如何或在何处使用dynamicCall(或触发QAxWidget的适当插槽),GUI都会锁定,直到ActiveX控件完成其操作


是否有任何方法可以将此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
进行不必要的子类化。