在qt界面中调用matlab engine并嵌入Matlab cmd Window
环境:win10+QT(编译器:MSVC 2017 64-bit)+Matlab 2016a 64-bit
先上效果图:
主体思路如下(参考:https://blog.csdn.net/humanking7/article/details/86040954,做了些简化)
主要操作
涉及到的操作主要有:
- qt下启动线程操作;
- qt下调用matlab engine 的配置;
- qt嵌入外部程序的窗口;
- qt调用windows api;
多线程Qthread: https://blog.csdn.net/naibozhuan3744/article/details/81174681
qt下调用matlab engine的配置 http://blog.sina.com.cn/s/blog_89a45b020102vrr8.html
窗口的嵌入 https://blog.csdn.net/u013394556/article/details/78534833 https://blog.csdn.net/r5014/article/details/79286444
windows api 的调用 https://blog.csdn.net/ys_073/article/details/7770693>
代码和解释
UseMatlab.pro
#-------------------------------------------------
#
# Project created by QtCreator 2019-04-22T16:00:00
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = UseMatlab
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp \
usematlabthread.cpp
HEADERS += \
mainwindow.h \
usematlabthread.h
FORMS += \
mainwindow.ui
#添加matlab类库
INCLUDEPATH +=$$quote(D:\Program Files\MATLAB\R2016a\extern\include) #matlab的extrern路径,有空格所以要用$$quote()
LIBS +=$$quote(D:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft\libeng.lib)
LIBS +=$$quote(D:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft\libmat.lib)
LIBS +=$$quote(D:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft\libmx.lib)
LIBS +=$$quote(D:\Program Files\MATLAB\R2016a\extern\lib\win64\microsoft\libmex.lib)
#添加windows库
LIBS +=User32.LIB
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
这里要注意的是添加matlab类库和windows库
usematlabthread.h
#ifndef USEMATLABTHREAD_H
#define USEMATLABTHREAD_H
//qt开启线程相关
#include <QThread>
#include <QMutex>
#include <QDebug>
//matlab相关
#include "engine.h"
#include "mat.h"
class UseMatlabThread: public QThread
{
Q_OBJECT //注意,没有Q_OBJECT没办法添加 signals
public:
explicit UseMatlabThread(QObject *parent=nullptr);
void closeThread();
signals:
void detach_cmd();
protected:
virtual void run();//新线程的执行的函数
public:
volatile bool isStop; //易失变量?,需要用volatiale声明?,可以用于控制线程的开关
};
#endif // USEMATLABTHREAD_H
usematlabthread.cpp
#include "usematlabthread.h"
UseMatlabThread::UseMatlabThread(QObject *parent):QThread (parent)
{
isStop=false;
}
void UseMatlabThread::closeThread()
{
isStop=true;
}
void UseMatlabThread::run()
{
Engine *Matlab;
//open engine
if (!(Matlab = engOpen("\0")))
{
qDebug()<<"Can't start MATLAB engine";
return ;
}
emit detach_cmd();
while(1)
{
if(isStop)
{
//close engine
engClose(Matlab);
return;
}
qDebug()<<"use Matlab Engine"<<QThread::currentThreadId();
sleep(1);
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWindow>
#include <Windows.h>
#include "usematlabthread.h" //用于启动matlab engine
#include "matlabcmddlg.h" //用于将matlab engine嵌入对话框
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void openME();
void closeME();
//void beginME();
void finishME();
void detach_mcmd();
private:
Ui::MainWindow *ui;
UseMatlabThread *thread1;
MatlabCmdDlg *M_dialog1;
};
//#pragma execution_chaeacter_set("utf-8")
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
thread1=new UseMatlabThread;
connect(ui->pushButton_openME,SIGNAL(clicked()),this,SLOT(openME()));
connect(ui->pushButton_closeME,SIGNAL(clicked()),this,SLOT(closeME()));
connect(thread1,SIGNAL(detach_cmd()),this,SLOT(detach_mcmd()));
connect(thread1,SIGNAL(finished()),this,SLOT(finishME()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::detach_mcmd()
{
WId wid=(WId)FindWindow(NULL, L"MATLAB Command Window");
//WId wid=(WId)FindWindow(L"Edit", NULL);
//wid=(WId)FindWindow(nullptr,nullptr);
qDebug()<<"cmd win id"<<wid<<endl;
QWindow * m_window=QWindow::fromWinId(wid);
QWidget *m_widget;
m_widget = QWidget::createWindowContainer(m_window, this->ui->widget_cmd);
m_widget->setMinimumSize(841,111);
m_widget->setMaximumSize(16777215,16777215);
m_widget->show();
}
void MainWindow::openME()
{
thread1->start();
thread1->isStop=false;
qDebug()<<"主线程 id"<<QThread::currentThreadId();
}
void MainWindow::closeME()
{
thread1->closeThread();
thread1->wait();
}
void MainWindow::finishME()
{
qDebug()<<"finish";
}