betway必威-betway必威官方网站
做最好的网站

betway必威官方网站车牌识别,别浪费生命了

大家什么原因还在用MFC,历史代码的维护么。一个软件刚开始技术选型的话就别选MFC了,都是C 用Qt比MFC开发快多了。Qt上手很快,有C 基础几天就完全上手了。感觉MFC是给机器设计的,Qt是给程序员设计的,MFC太反人类了;

NumIdentify.cpp

 

betway必威官方网站 1

 

下面贴出代码,代码很简单。
NumIdentify.h

发布

首先得装上个Qt,就Qt5.8好了,我选择了MSVC版本的,因为我要在VS上调用Qt。另外下载qs-vs-tools工具,装好之后,稍加配置,就可以愉快地写代码了。VS配合Qt使用,美滋滋。。。

 

用c 写界面,用MFC库和Qt库的比较多。Qt相比MFC而言,更加的简易,更加容易上手,所以博主选择了用Qt写界面(其实是我MFC太生疏了,逃。。。)

我曾经使用过QT和MFC来开发过软件,我想和大家分享我使用他们时所体会的不同之处。

界面

 

#include "NumIdentify.h"
#include <qgraphicsscene.h>
#include <qpixmap.h>
#include <ImageProcessor.h>
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <qfont.h>

NumIdentify::NumIdentify(QWidget *parent)
    : QDialog(parent)
{
    //ui.setupUi(this);
    this->setGeometry(50, 50, 1200,500);
    init();//this function can create the ui

}

//INIT finish arranging layout and appearance
void NumIdentify::init()
{
    //create widgets and add them into layout
    //the Top Left Layout
    ImageLabel1 = new QLabel(tr("Original Image"));
    scene1 = new QGraphicsScene;
    Image1 = new QGraphicsView(scene1);

    LeftLayout = new QVBoxLayout;

    LeftLayout->addWidget(ImageLabel1);
    LeftLayout->addWidget(Image1);
    LeftLayout->setAlignment(Qt::AlignCenter);

    //set the right layout
    ImageLabel2 = new QLabel(tr("Cut Image"));
    scene2 = new QGraphicsScene;
    Image2 = new QGraphicsView(scene2);
    //
    TextLabel = new QLabel(tr("Identified Text"));
    TextShow = new QTextEdit();
    RightLayout = new QVBoxLayout;
    RightLayout->addWidget(ImageLabel2);
    RightLayout->addWidget(Image2);
    RightLayout->addWidget(TextShow);
    RightLayout->setAlignment(Qt::AlignCenter);

    //set the bottom layout
    OpenBtn = new QPushButton(tr("Open File"));
    CleanBtn = new QPushButton(tr("Clean"));
    IdentifyBtn = new QPushButton(tr("Identify"));
    StatusLabel = new QLabel("Status:");
    Progress = new QProgressBar;
    BottomLayout = new QHBoxLayout;
    BottomLayout->addWidget(OpenBtn);
    BottomLayout->addWidget(CleanBtn);
    BottomLayout->addWidget(IdentifyBtn);
    BottomLayout->addWidget(StatusLabel);
    BottomLayout->addWidget(Progress);

    //set the top layout
    TopLayout = new QHBoxLayout;
    TopLayout->addLayout(LeftLayout);
    TopLayout->addLayout(RightLayout);

    //set the general layout
    MainLayout = new QVBoxLayout(this);
    MainLayout->addLayout(TopLayout);
    MainLayout->addLayout(BottomLayout);
    setLayout(MainLayout);

    //上面的语句完成了UI的初始化
    //以下语句将控件和函数联系起来,主要是一些connect函数
    connect(OpenBtn, SIGNAL(clicked()), this, SLOT(onOpenFile()));
    connect(CleanBtn, SIGNAL(clicked()), this, SLOT(onClean()));
    connect(IdentifyBtn, SIGNAL(clicked()), this, SLOT(onIdentify()));
}

//SHOWIMAGE show image designated view
//when view=0,show image in scene1
//when view=1,show image in scene2
//this function must be used after scene1 and scene2 were created.
void NumIdentify::showImage(QImage img, uint view)const
{
    QPixmap temp = QPixmap::fromImage(img,Qt::ColorOnly);
    if (view == 0)
    {
        scene1->addPixmap(temp);
    }
    else if (view == 1)
    {
        scene2->addPixmap(temp);
    }
}

void NumIdentify::onOpenFile()
{
    QString path0 = QFileDialog::getOpenFileName(this, tr("Open..."), tr("D:\"), tr("Images (*.jpg *.jpeg)"));
    if (path0.length() == 0) {
        QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files."));
        return;//退出
    }
    string path = path0.toStdString();//QString to string
    i = new ImageProcessor(path);

    //显示原始图形
    showImage(i->Mat2QImage(i->originalImage), 0);
}

void NumIdentify::onIdentify()
{
    if (i != NULL)//存在ImagegProcessor对象才能识别啊
    {
        i->action();
    }
    else if (i == NULL)
    {
        return;
    }
    //显示切割图像accurateImage
    //Mat temp;
    //cvtColor(i->accurateImage, temp, CV_GRAY2BGR);
    showImage(i->Mat2QImage(i->accurateImage), 1);

    //显示切割出来的字符
    string tmp="";
    for (int k = 0; k < i->recognizedCharacters.size(); k  )
        tmp = tmp   i->recognizedCharacters[k];

    QString tmp1 = QString::fromStdString(tmp);
    TextShow->setFontWeight(QFont::Bold);//粗体显示
    TextShow->setFont(QFont("Timers", 28, QFont::Bold));
    TextShow->setPlainText(tmp1.toUtf8());
}

void NumIdentify::onClean()
{
    //QMessageBox::information(this, tr("just try"), tr("test"));
    //先把所有的显示给清空
    scene1->clear();
    scene2->clear();
    TextShow->clear();
    i = NULL;
}

 

#pragma once
#pragma execution_character_set("utf-8")
#include <QtWidgets/QDialog>
#include <ImageProcessor.h>
//#include "ui_NumIdentify.h"
#include <qlabel.h>
#include <qpushbutton.h>
#include <qtextedit.h>
#include <qprogressbar.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <qgraphicsview.h>

class NumIdentify : public QDialog
{
    Q_OBJECT

public:
    NumIdentify(QWidget *parent = Q_NULLPTR);

private:
    //Ui::NumIdentifyClass ui;
    QLabel *ImageLabel1;
    QLabel *ImageLabel2;
    QLabel *TextLabel;
    QLabel *StatusLabel;

    QPushButton *OpenBtn;
    QPushButton *CleanBtn;
    QPushButton *IdentifyBtn;

    QGraphicsView *Image1;
    QGraphicsView *Image2;

    QProgressBar *Progress;

    QTextEdit *TextShow;

    //the followings are layout
    QVBoxLayout *LeftLayout;
    QVBoxLayout *RightLayout;
    QHBoxLayout *TopLayout;
    QHBoxLayout *BottomLayout;
    QVBoxLayout *MainLayout;

    //two scenes
    QGraphicsScene *scene1;
    QGraphicsScene *scene2;

    //一个ImageProcessor类的指针
    ImageProcessor *i=NULL;

public:
    void showImage(QImage img,uint view)const;//this function 
    void init();

private slots:
    void onOpenFile();
    void onClean();
    void onIdentify();
};

 

完毕

使用MFC是可以国际化的,但是需要将每一个字符串放在一个字符串表中,在代码中到处使用LoadString(IDENTIFIET)。然后转化这些资源到DLL中,翻译字符串到所需要的语言,改变图形界面,然后调用程序使用这个DLL。整个过程是如此的繁琐,可谓牵一发而动全身。考虑的事情要面面俱到。

下面是我设计的界面,觉得怎么样呢?是不是一股浓重的乡村重金属风格的画风迎面而来。。。哈哈,不管了,先将就弄成这样,以后再更改。

Qt的消息机制是建立在SIGNAL()发送和SLOT()接受的基础上的。这个机制是对象间建立联系的核心机制。利用SIGNAL()可以传递任何的参数。他的功能非常的强大。可以直接大传递信号给SLOT(),因此可以清楚的理解要发生的事情。一个类所发送的信号的数量通常非常的小(4或者5),并且文档也非常的齐全。这让你感觉到一切尽在掌握之中。SIGNAL/SLOT机制类似于Java中listener机制,不过这种机制更加轻量级,功能更齐全。(这种机制确实貌似简单清晰了一些)

 

一旦你购买了Visual Studio,你将免费的获得MFC SDK。Qt在Unix上是可以免费获得其遵守GPL版权的版本(译者注:现在在windows 上也可以免费获得其GPL版本)。如果要开发不公开源代码的软件,必须购买Qt的授权。在特定平台下,每个开发者购买一个永久性授权,并获得一年的技术支持。(译者注:后面关于购买价格等问题删去,因为价格不固定,如果有疑问请到官方网站查询价格)

 

 

 

 

 

 

消息循环

使用MFC,如果要显示unicode,在编译链接的时候必须用到特殊的参数(和改变可执行文件执行的入口),必须在每个string前面加上T,将char修改成TCHAR,每个字符串处理函数(strcpy(), strdup(), strcat()...... )都要改变成另外的函数名。更令人恼火的是支持Unicode的软件竟然不能和不支持Unicode的DLL一起工作。当使用外部DLL来开发的时候

 

 

 

 

 

我并非一个职业作家,这篇文章可能看起来不如专业的杂志和网站上的那么条理清晰。但是,我在这里是用我自己的语言来表达我自己的经验,希望能和你分享。英语比不是我的母语,所以可能会有一些用词古怪,词句错误之处,请发信给我,我可以改正他们。

根据你所说的方面,简单比较一下:
1.开发速度
整体来说可能MFC会快捷一些,因为windows平台的开发工具大多很智能,因为立足于windows的开发人群很广,从菜鸟到专业人士,但是QT由于基于Linux,可用的开发工具不多,大都比较专业,多是第三方产品,而且集成度不大,第三方库也没有MFC的多,从这一点MFC略胜一筹,但是QT自从被Nokia收购后,官方发布了跨平台集成开发环境QTCreator,所以之后走向就不好说了,个人总体感觉QT Creator和VS.net差距比较大,还需改进
但是从库本身来说QT集成的功能较MFC庞大,而且使用的封装技术信号和槽也是比较受到赞许的,比如QT Script为QT提供嵌入式脚本,QT界面库支持CSS,所以QT做出来的界面比MFC要好,而且比较容易,MFC就需要借助第三方库了。因为MFC是浅层封装(最新的2008 sp1加入了BCG的高级界面库,可能有所改善)windows SDK,以降低使用windows SDK引起的开发效率的降低,和开发难度的增加。所以QT库是比MFC优秀的,两个库都经受了时间的考验,稳定性都很高,Bug几乎没有
2.运行效率
MFC由于其浅层封装的特点,所以运行效率是比较高的,加上vc对windows的针对性优化,整体性能是比较高的,但是如果加入第三方库就不敢保证了QT因为库比较庞大,封装层次较深,所以运行效率较MFC为低,但是在现在的机器配置下,C#大家都不介意了,这些会引起人们的介意吗?
3.应用范围,现在windows的普及范围谁能比过,所以MFC的客户量比较多,QT主要是Linux下的开发人员在使用,但MFC也只是得益于windows(感觉又是一次捆绑战略),MFC不支持嵌入式开发(主要指手机平台),但是QT有对应的模块

在发布基于MFC的软件时,必须依靠存在于客户电脑上的MFC。但是这是不安全的,同样是MFC42.dll,可以基于相同的库得到3个不同的版本。通常,需要检查是否拥有正确的MFC42.dll版本,如果不是,就升级它。但是升级MFC42.dll会改变很多软件的行为。这让我感到很不舒服,如果用户在安装我的软件以后导致其机器死机该怎么办?

QT使用的编译器是MinGW,即Linux下的GCC移植到windows的版本;MFC使用的编译器是Visual C
betway必威官方网站,QT的应用主要在Linux下,但是它本身是跨平台的,也支持其他操作系统,是现在比较著名的界面库,著名的KDE就是使用QT开发的。MFC是提供给VC的,但是它主要是代码库,不像VCL和编译器挂钩很多,但是MFC主要是对windows API的封装,所以只能用于windows平台

的。

 

速度

归根结底,Qt和MFC的差异在于其设计的差异。MFC的根本目的是访问包装起来的用C语言写的windows的API。 这绝非好的面向对象的设计模式,在很多地方,你必须提供一个包含15个成员的C语言的struct,但是其中只有一个与你所期望的相关,或者必须用旧式的参数来调用你的函数。MFC还有许多让人摸不着头脑的地方,函数名没有任何的连续性。比如,如果你创建了一个graphical类,直到调用了creat()以后该类才会被创建。然而对dialogs,必须要等到OnInitDialog()才能创建这个对象。奇怪的是到了views,创建该类的函数名竟然成了OnInitUpdate(),......你自己创建一个类用他们的方式调用它,你的程序崩溃了。

信息数以千计,遗憾的是,要分清楚这些分繁芜杂的消息是很困难的,并且关于这方面的文档并不能很好的解决这些问题。

 

 

 

MFC是事件驱动的架构。要执行任何操作,都必须是对特定的消息作出响应。Windows对应用程序发送的

创建界面

 

Qt这个C 的图形库由Trolltech在1994年左右开发。它可以运行在Windows,Mac OSX, Unix,还有像Sharp Zaurus这类嵌入式系统中。Qt是完全面向对象的。Document/View modelMFC编程需要使用Document/View模式以及模板(template),如果不使用的话,编程将变得异常困难。而且,模板(template)设定了固定的结构,若所需结构乃模板未定义之结构,则编程难已。例如,划分一区域使显示两个视图(view)于两个文档(document)。还有一个经常的问题是:模板(template)创建了视图(view)却无法访问(access)它,文档(document)要做完所有事情,但是这经常会出现问题。 (这种数据和视图分开的设计模式也是一种不错的模式,不应该成为否定MFC的理由)Qt不强制使用任何设计模式。如果你认为恰当,使用Document/view没有任何问题。不使用也没有任何问题。

本文由betway必威发布于编程开发,转载请注明出处:betway必威官方网站车牌识别,别浪费生命了

TAG标签: betway必威
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。