Qt+OpenCV(二)创建完整的Qt+OpenCV项目

        时间已经隔得比较久了,不知不觉就已经到了开学的日子。只能说,我还是……太懒了……

        (再次承认我对自己的认识很客观,写的时候是开学,发布的时候已经放假回家了……)

        第三章的内容是创建一个完整的Qt+OpenCV项目,这一章以及后面的第四章的内容,我其实都是在差不多一个月前学习和简单尝试过的,然后就……放飞自我了……刚好,现在重新整理一下,也方便我回顾回顾之前已经有些生疏的内容。

        稍微急功近利一点,这两章的内容尽量简单速食一些。

        第三章的主要内容包括有:Qt项目结构和构建、设计模式、应用程序样式、应用程序语言(大概理解就是系统展示的语言可以是汉语、英语、法语等,更加面向国际)、插件(本文仅提及,未介绍)。

        接下来逐个简单总结。

目录

        1 后台

        1.1 qmake工具

        1.2 元对象编译器(moc)

        1.3 用户界面编译器(uic)

扫描二维码关注公众号,回复: 15232332 查看本文章

        2 设计模式

        3 资源系统

        4 样式

        4.1 选择器类型

        4.2 子控件

        4.3 伪状态

        4.4 级联

        5 多语言支持

    

        1 后台

        首先,参考书中介绍了程序运行的后台情况。

        1.1 qmake工具

        简单说来,qmake工具是使用.pro文件的内部信息帮助生成makefile的一个程序。通过使用qmake,可以为正确编译和构建应用程序生成所必须的命令并将其存入构建文件夹中(即运行后标注为build-*的文件夹)。构建文件夹是创建和执行应用程序的地方。

        下面通过注释介绍.pro文件中部分代码行的含义。

QT       += core gui
#添加core gui模块到应用程序中


TARGET=learn_opencv
TEMPLATE=app
#表明项目工程名是learn_opencv
#工程项目是一个应用程序



SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui
#项目中包含的头文件、源文件和用户界面文件

        当qmake处理完Qt工程项目以后,它将开始寻找工程项目中提到的源文件。每个C++应用程序在其某个源文件中有一个主函数,Qt应用程序的主函数由Qt Creator自动生成。简单看下main函数自动生成的内容:

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
    //创建了 QApplication类的一个实例,
    //并将应用程序的参数(通过命令行或终端)传递给名为a的新实例
    //创建并显示MainWindow类的一个实例
    //调用QApplication类的exec()函数,使应用程序进入主循环,直到窗口关闭

        1.2 元对象编译器(moc)

        Qt中的某些功能在标准C++编程中是没有的(如信号和槽、添加动态属性等),通过名为moc的Qt内部编译器,可以实现标准C++以外的功能。在Qt代码被传递给真正的C++编译器之前,moc工具可以处理类头文件(即我们编辑的头文件)来生成所需要的代码,支持Qt的特有功能。在构建文件夹中,这些生成的源文件都以moc_开头。

        moc会用包含Q_OBJECT宏的Qt类搜索所有头文件,这个宏必须一直包含在需要支持信号、槽和其他Qt所支持特性的Qt类中。

        1.3 用户界面编译器(uic)

        构建带有用户界面的Qt应用程序时,会执行名为uic的Qt内部工具,处理.ui文件将其转换为C++程序可用的类和源代码。在这里。mainwindow.h文件被转换为ui_mainwindow.h文件。

        ui_mainwindow.h文件中名为Ui_MainWindow的类有setupUi和retranslateUi两个函数。前者是在mainwindow.h函数中自动添加进MainWindow类构造函数的,它负责根据mainwindow.ui文件中的设置信息设置用户界面的相关内容。

        Qt的所有生成文件都保存到构建文件夹后,像所有其他C++程序一样,文件被传递给C++编译器,通过被编译、被链接,最后在构建文件夹中创建应用程序。对Windows用户来说,通过Qt Creator直接运行程序是可以的,但直接在构建文件夹中运行程序会出现很多错误信息导致应用程序崩溃或无法启动,这个问题将在后面学习如何解决。(这里是书中的说法,但是自己咨询的时候还是可以的,具体如何等第十章再看)

        2 设计模式

        设计模式是解决软件开发问题的最结构化的方法,有助于确保为程序添加的所有内容都使用了一些预定义的模板式结构。

        关于设计模式的内容理解的不是很深入,所以打算后面实践时再深入学习。

        3 资源系统

        Qt资源系统应该算是Qt应用中比较常用的一部分了,在没学习本书之前,我就已经有需要通过资源系统给应用程序添加图标等的应用需求了。

        通过资源系统可以将资源文件(如字体、图标、图像、翻译文件、样式表文件等等)添加至应用程序(和库)中。

        接下来简单介绍如何添加资源文件。

        首先选择新建一个Qt Resource File文件,即添加一个.qrc文件到项目中。

 对于新建的文件,右击Open in Editor可以选择添加资源。

 通过单击Add Prefix,可添加前缀,如/images/,单击Add Files,可添加一个资源文件。之后,便可以很方便的添加资源了。如添加按钮图标:

        4 样式

        Qt在应用程序中可以使用QStyle类和样式表支持样式化。前者是Qt中所有样式的基类,封装了Qt用户界面的样式,本篇暂且不谈,留到后续学习。

        Qt样式表在语法上与HTML CSS(层叠样式表)几乎一样。右击一个控件,可以设置其styleSheet属性。

        

         

        4.1 选择器类型

        Qt样式表中的样式规则由“选择器”和“声明”组成,选择器用于指定将使用样式的控件,而声明就是样式本身。恰当地使用选择器可以极大地减少样式表所需的代码量来改变Qt应用程序的外观。

        

样式表选择器及描述
选择器的类型 例子 描述
通用选择器 * 所有控件
类型选择器 QPushButton 指定类型的控件及其子类
属性选择器 QPushButton[text='Browsw'] 其指定属性设置为指定值的控件
类选择器 .QPushButton 具有指定类型的控件,但不包括其子类
ID选择器 QPushButton#inputPushButton 具有指定类型的控件和objectName的控件
后代选择器 QDialog QPushButton 作为另一个控件子控件的控件
子选择器 QDialog > QPushButton 作为另一个控件直接子控件的控件

        4.2 子控件

        子控件是复杂控件内的孩子控件,可以通过“::”选择子控件,如QSpinBox::down-button,即选择QSpinBox中向下的箭头按钮。

        4.3 伪状态

        每个控件都可以有一些伪状态,如鼠标悬停、按键等等,可以使用“:”操作符在样式表中选择伪状态,如QRaidoButton:!hover{color: black}。

        4.4 级联

        可以为整个应用程序、父控件或子控件设置样式表,每个控件的样式由级联规则决定,即如果为父控件或应用程序设置了样式表,那么每个控件均可获得这些样式规则。如下为对主窗口设置了样式表:

*
{
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;
}

       

 

         如图可见,子对话框窗口的样式也发生了改变。

        5 多语言支持

        接下来,整理如何使用Qt框架支持多种语言的应用程序,在这里需要依赖一个比较容易使用的类——QTranslator。这是一个负责处理输出文本国际化的主要Qt类,需要确定几点:

        1.构建工程项目时,使用默认语言(如英语)。

        2.确保代码中的所有文字字符串(或者说,需要翻译的所有语言)都包含在tr()函数中

        3.确保在项目文件中指定翻译文件,即需要有TRANSLTIONS来指定它们。例如,需要使用德语和土耳其语的翻译,可在.pro文件中添加:

TRANSLTIONS =translations_de.ts translation_tr.ts

(翻译文件的命名最好用包含的语言代码命名,更便于辨认)

        4.使用Qt的lupdate工具创建TS文件。lupdate可以搜索所有的源代码和UI文本中的可翻译文本,然后创建或更新TS文件(.ts文件)。负责翻译应用的人员可以使用Qt语言工具打开TS文件,使用简单的用户界面即可翻译应用程序。

        lupdate位于Qt安装目录中的bin文件夹中,类似:E:\Qt\Qt5.14.2\5.14.2\mingw73_64\bin。

        如果运行lupdate出现任何问题,可以切换到工程目录文件夹使用命令行运行,如下:

         5.使用Qt语言工具翻译所有需要的字符串。在项目中添加.ts文件后,选择用Qt Linguist打开文件,用该工具对可翻译元素进行翻译。(记得在退出前进行保存)

     

        6.利用翻译的TS文件创建QM文件,它们是压缩的二进制Qt语言文件。完成该步骤需要使用Qt Irelease工具。(使用方法类似lupdate,将命令中的lupdate替换为Irelease即可)

        7.将QM文件添加到应用程序资源中。(与添加图片资源类似)

        8.接下来,即可使用QTranslator类赋予应用程序多语言功能,使之在运行时能在不同的语言之间切换。在尝试的示例项目中,进行翻译。

        首先将QTranslator添加到mainwindow.h中,并在窗口类(MainWindow类)中定义两个私有QTranslator对象。

QTranslator *turkishTranslator;
QTranslator*germanTranslator;//土耳其语翻译 德语翻译

 此外,在构造函数中加载翻译文件(在loadSetting()之后)。

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

        接下来,创建一个主菜单,并添加三个子项,如下:

 对每个菜单子项添加信号和槽机制,分别如下。需要注意的是,对于默认语言,需要删除翻译器,而不再是添加。

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);
}

        为了确保应用程序能够重新翻译并重新加载上屏幕上的对象元素,需要使用QMainWindow类的changeEvent。

        每当安装或删除翻译器时,都会有一个“语言更改”事件发送到应用程序的所有窗口,要捕获该事件,并确保窗口能够在语言更改时重新加载,需要重写程序中的changeEvent函数。将下面代码添加在mainwindow.h文件中的MainWindow类的受保护成员中:

void changeEvent(QEvent*event);

        并在mainwindow.cpp中重写changeEvent函数。

void MainWindow::changeEvent(QEvent *event){
    //如果更改事件是语言更改 则翻译窗口  否则照常
    if(event->type()==QEvent::LanguageChange){
        ui->retranslateUi(this);
    }
    else{
        QMainWindow::changeEvent(event);
    }
}

        由此即可在应用程序中尝试不同的语言的切换了。

        6 插件

        在应用程序中使用插件是扩展应用程序最强大的方法之一。一个插件就是一个简单的库,可以在运行时加载和使用插件以处理特定的任务,但它不能像一个独立的应用程序那样执行,而依赖于使用它的应用程序。

        (这篇文应该差不多是快六个月前写的,当时因为个人比较懒再就是开始新的学习环境,写到插件这里就一直没动过了,回过头来看,虽然记录得不太全面,但是字数上已经超过我的预期了,所以刚好想起来就先发布这些内容吧,有关插件的部分之后单独总结总结。)

猜你喜欢

转载自blog.csdn.net/qq_45792470/article/details/126147938