《OpenCV3和Qt5计算机视觉应用开发》学习笔记第3章

第三章 创建完整的Qt+OpenCV项目,本章学习记录的内容包括:
1.Qt应用程序样式
2.Qt应用程序多语言
3. 如何在Qt中创建和使用插件

1..接第二章的项目Hello_Qt_OpenCV,在它的基本上添加样式表,
样式表内容为:

*
{
font: 75 11pt;
background-color: rgb(220, 220, 220);
}
QPushButton, QLineEdit, QGroupBox
{
border: 2px solid rgb(0, 0, 0);
border-radius: 10px;
min-width: 80px;
min-height: 35px;
}
QPushButton
{
background-color: rgb(0, 255, 0);
}
QLineEdit
{
background-color: rgb(0, 170, 255);
}
QPushButton:hover, QRadioButton:hover, QCheckBox:hover
{
color: red;
}
QPushButton:!hover, QRadioButton:!hover, QCheckBox:!hover
{
color: black;
}

 点击MainWindow类,选择styleSheet属性,打开属性对话框,输入上面的qss代码,如下所示:

点击OK按钮,马上就可以看到效果了

编译运行结果如下:

2.Qt应用程序多语言

首先要生成翻译文件,在项目工程文件中(*.pro)添加翻译文件即
TRANSLATIONS = translation_de.ts translation_tr.ts, 然后选择菜单【工具】=》【外部】=》【Qt语言家】=》【更新翻译lupdate】就生成了以上两个翻译文件。

也可以用命令来执行C:\Qt\Qt5.12.9\5.12.9\msvc2017_64\bin\lupdate.exe Hello_Qt_OpenCV.pro都可以生生翻译文件,然后用linguist.exe打开 翻译文件。

对每一条文案进行翻译。

然后点菜单栏【文件】=》【发布】即可生成*.qm的二进制语言文件。

接着把二进制的语言文件添加到资源文件中。

编写应用语言的代码:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    loadSettings();

    turkishTranslator = new QTranslator(this);
    turkishTranslator->load(":/translations/translation_tr.qm");

    germanTranslator = new QTranslator(this);
    germanTranslator->load(":/translations/translation_de.qm");
}

在菜单中添加三个子菜单项

编写对应该的槽函数及语言切换事件函数

protected:
    void changeEvent(QEvent *event);

private slots:
    void on_actionTurkish_triggered();
    void on_actionEnglish_triggered();
    void on_actionGerman_triggered();

private:
    Ui::MainWindow *ui;

    void loadSettings();
    void saveSettings();

    QTranslator *turkishTranslator;
    QTranslator *germanTranslator;
void MainWindow::changeEvent(QEvent *event)
{
    if(event->type() == QEvent::LanguageChange)
    {
        ui->retranslateUi(this);
    }
    else
    {
        QMainWindow::changeEvent(event);
    }
}

void MainWindow::on_actionTurkish_triggered()
{
    qApp->installTranslator(turkishTranslator);
}

void MainWindow::on_actionGerman_triggered()
{
    qApp->installTranslator(germanTranslator);
}

void MainWindow::on_actionEnglish_triggered()
{
    qApp->removeTranslator(turkishTranslator);
    qApp->removeTranslator(germanTranslator);
}

运行效果:

3.QT的插件创建与使用

首先创建一个名为median_filter_plugin插件项目,【文件】=》【新建文件或项目】=》【Library】=》【C++ Library】,选择相应的文件目录,按操作指引创建项目。

 一定要将类型选为“Shared Library”,然后输入“median_filter_plugin”作为名称并单击【下一步】。选择工具箱类型作为桌面。在“Select Required Modules”页面中,确保只选中了“QtCore”,并继续单击【下一步】(最后单击【完成】),不需要更改任何选项,直到最终进入Qt Creator的代码编辑器页面。

 添加代码

//cvplugininterface.h
#ifndef CVPLUGININTERFACE_H
#define CVPLUGININTERFACE_H

#include <QObject>
#include <QString>
#include "opencv2/opencv.hpp"

class CvPluginInterface
{
public:
    virtual ~CvPluginInterface() {}
    virtual QString description() = 0;
    virtual void processImage(const cv::Mat &inputImage, cv::Mat &outputImage) = 0;
};

#define CVPLUGININTERFACE_IID "com.amin.cvplugininterface"
Q_DECLARE_INTERFACE(CvPluginInterface, CVPLUGININTERFACE_IID)

#endif // CVPLUGININTERFACE_H
//median_filter_plugin.h

#ifndef MEDIAN_FILTER_PLUGIN_H
#define MEDIAN_FILTER_PLUGIN_H

#include "median_filter_plugin_global.h"

#include "cvplugininterface.h"

class MEDIAN_FILTER_PLUGINSHARED_EXPORT Median_filter_plugin: public QObject, public CvPluginInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.amin.cvplugininterface")
    Q_INTERFACES(CvPluginInterface)
public:
    Median_filter_plugin();
    ~Median_filter_plugin();
    QString description();
    void processImage(const cv::Mat &inputImage, cv::Mat &outputImage);
};

#endif // MEDIAN_FILTER_PLUGIN_H
//median_filter_plugin_global.h
#ifndef MEDIAN_FILTER_PLUGIN_GLOBAL_H
#define MEDIAN_FILTER_PLUGIN_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(MEDIAN_FILTER_PLUGIN_LIBRARY)
#  define MEDIAN_FILTER_PLUGINSHARED_EXPORT Q_DECL_EXPORT
#else
#  define MEDIAN_FILTER_PLUGINSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // MEDIAN_FILTER_PLUGIN_GLOBAL_H
//median_filter_plugin.h
#include "median_filter_plugin.h"


Median_filter_plugin::Median_filter_plugin()
{
}

Median_filter_plugin::~Median_filter_plugin()
{

}

QString Median_filter_plugin::description()
{
    return "This plugin applies median blur filters to any image."
           " This plugin's goal is to make us more familiar with the"
           " concept of plugins in general.";
}

void Median_filter_plugin::processImage(const cv::Mat &inputImage, cv::Mat &outputImage)
{
    cv::medianBlur(inputImage, outputImage, 5);
}

工程文件设置

#-------------------------------------------------
#
# Project created by QtCreator 2017-09-10T12:23:47
#
#-------------------------------------------------

QT       -= gui

TARGET = median_filter_plugin
TEMPLATE = lib

#win环境配置
win32:{
    CONFIG(debug, debug|release){
        DESTDIR += $$PWD/../bin/win64d
        LIBS += -L$$PWD/../lib/win64d -lopencv_world480d
    }else{
        DESTDIR += $$PWD/../bin/win64
        LIBS += -L$$PWD/../lib/win64 -lopencv_world480
    }
}

INCLUDEPATH += ../Include

CONFIG += plugin

DEFINES += MEDIAN_FILTER_PLUGIN_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as 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

SOURCES += \
        median_filter_plugin.cpp

HEADERS += \
        median_filter_plugin.h \
        median_filter_plugin_global.h \  
        cvplugininterface.h

unix {
    target.path = /usr/lib
    INSTALLS += target
}

win32: {
    include(c:/dev/opencv/opencv.pri)
}

unix: !macx{
    CONFIG += link_pkgconfig
    PKGCONFIG += opencv
}

unix: macx{
INCLUDEPATH += /usr/local/include
LIBS += -L/usr/local/lib \
    -lopencv_world
}

编译生成median_filter_plugin.dll,根据编译模式把动态库放到bin/win64d/filter_plugins或bin/win64/filter_plugins目录下.

然后创建应用程序Plugin_User

打开mainwindow.ui界面,设计相应控件及布局。

把cvplugininterface.h文件添加到项目中,编写mainwindow.h和mainwindow.cpp的相关代码。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QPluginLoader>
#include <QFileInfoList>
#include "opencv2/opencv.hpp"
#include "cvplugininterface.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_inputImgButton_pressed();

    void on_helpButton_pressed();

    void on_filterButton_pressed();

private:
    Ui::MainWindow *ui;
    void getPluginsList();
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

#define FILTERS_SUBFOLDER "/filter_plugins/"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    getPluginsList();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::getPluginsList()
{
    QDir filtersDir(qApp->applicationDirPath() + FILTERS_SUBFOLDER);
    QFileInfoList filters = filtersDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files, QDir::Name);
    foreach(QFileInfo filter, filters)
    {
        if(QLibrary::isLibrary(filter.absoluteFilePath()))
        {
            QPluginLoader pluginLoader(filter.absoluteFilePath(), this);
            if(dynamic_cast<CvPluginInterface*>(pluginLoader.instance()))
            {
                ui->filtersList->addItem(filter.fileName());
                pluginLoader.unload(); // we can unload for now
            }
            else
            {
                QMessageBox::warning(this, tr("Warning"),
                                     QString(tr("Make sure %1 is a correct plugin for this application<br>"
                                                "and it's not in use by some other application!")).arg(filter.fileName()));
            }
        }
        else
        {
            QMessageBox::warning(this, tr("Warning"),
                                 QString(tr("Make sure only plugins exist in plugins folder.<br>"
                                            "%1 is not a plugin.")).arg(filter.fileName()));
        }
    }

    if(ui->filtersList->count() <= 0)
    {
        QMessageBox::critical(this, tr("No Plugins"), tr("This application cannot work without plugins!"
                                                         "<br>Make sure that filter_plugins folder exists "
                                                         "in the same folder as the application<br>and that "
                                                         "there are some filter plugins inside it"));
        this->setEnabled(false);
    }
}

void MainWindow::on_inputImgButton_pressed()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Input Image"), QDir::currentPath(), tr("Images") + " (*.jpg *.png *.bmp)");
    if(QFile::exists(fileName))
    {
        ui->inputImgEdit->setText(fileName);
    }
}

void MainWindow::on_helpButton_pressed()
{
    if(ui->filtersList->currentRow() >= 0)
    {
        QPluginLoader pluginLoader(qApp->applicationDirPath() + FILTERS_SUBFOLDER + ui->filtersList->currentItem()->text());
        CvPluginInterface *plugin = dynamic_cast<CvPluginInterface*>(pluginLoader.instance());
        if(plugin)
        {
            QMessageBox::information(this, tr("Plugin Description"), plugin->description());
        }
        else
        {
            QMessageBox::warning(this, tr("Warning"), QString(tr("Make sure plugin %1 exists and is usable.")).arg(ui->filtersList->currentItem()->text()));
        }
    }
    else
    {
        QMessageBox::warning(this, tr("Warning"), QString(tr("First select a filter plugin from the list.")));
    }
}

void MainWindow::on_filterButton_pressed()
{
    if(ui->filtersList->currentRow() >= 0 && !ui->inputImgEdit->text().isEmpty())
    {
        QPluginLoader pluginLoader(qApp->applicationDirPath() + FILTERS_SUBFOLDER + ui->filtersList->currentItem()->text());
        CvPluginInterface *plugin = dynamic_cast<CvPluginInterface*>(pluginLoader.instance());
        if(plugin)
        {
            if(QFile::exists(ui->inputImgEdit->text()))
            {
                using namespace cv;
                Mat inputImage, outputImage;
                inputImage = imread(ui->inputImgEdit->text().toStdString());
                plugin->processImage(inputImage, outputImage);
                imshow(tr("Filtered Image").toStdString(), outputImage);
            }
            else
            {
                QMessageBox::warning(this, tr("Warning"), QString(tr("Make sure %1 exists.")).arg(ui->inputImgEdit->text()));
            }
        }
        else
        {
            QMessageBox::warning(this, tr("Warning"), QString(tr("Make sure plugin %1 exists and is usable.")).arg(ui->filtersList->currentItem()->text()));
        }
    }
    else
    {
        QMessageBox::warning(this, tr("Warning"), QString(tr("First select a filter plugin from the list.")));
    }
}

工程文件

#-------------------------------------------------
#
# Project created by QtCreator 2017-09-10T13:12:21
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Plugin_User
TEMPLATE = app

CONFIG += plugin

#win环境配置
win32:{
    CONFIG(debug, debug|release){
        DESTDIR += $$PWD/../bin/win64d
        LIBS += -L$$PWD/../lib/win64d -lopencv_world480d
    }else{
        DESTDIR += $$PWD/../bin/win64
        LIBS += -L$$PWD/../lib/win64 -lopencv_world480
    }
}

INCLUDEPATH += ../Include

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as 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


SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h \
    cvplugininterface.h

FORMS += \
        mainwindow.ui

win32: {
    include(c:/dev/opencv/opencv.pri)
}

unix: !macx{
    CONFIG += link_pkgconfig
    PKGCONFIG += opencv
}

unix: macx{
INCLUDEPATH += /usr/local/include
LIBS += -L/usr/local/lib \
    -lopencv_world
}

编译运行

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值