QQ:609162385 作者:予乔
本人接控件定制,软件制作。
作为一个软件工程师,编写一个好的软件最关键的地方就是程序的架构,又或者叫框架。如果框架没搭建好,那么后期维护,或者更改功能,就显得非常困难,这就是我在这里要记录的。
qml作为qt除widgets的又一种ui设计语言,给我们编写出更加炫酷的软件提供了基础。但新的东西出来总是有很多人摸索不到门路,或者走很多弯路,下面我们就来说说:
QML提供了很多方法来动态创建和管理QML对象。如Loader、RePeater、ListView、GridView和PathView等元素都支持动态对象管理。对象也可以在C++中被创建和管理,这是混合QML/C++应用程序的首选方式。QML也支持在JavaScript代码中动态创建对象,这在现有的QML元素不适合应用程序需要的情况下是很有用的,而且也不需要涉及C++组件。
qml编程必然是一个混合编程,很少有人能做到纯qml编程,因为有很多功能还是必须依靠c++,这就涉及到了框架问题;
我们下面来看一个程序的简单界面:
下方是我们程序的导航栏,主要有退出,设置,用户,主页面,打印,键盘等,
我们在编写这个程序的时候,将这几个模块分开由三个人写,最终如何能合并在一起成为一个程序,这就是框架的重要性了,
我们为没一个页面写一个pri项目管理文件,和一个pro个人工程文件,写的人在完成pro文件后,在将工程转为pri,添加到主程序框架中,所有的功能可以独立运行,也可以合并到主程序中运行。
下面贴出main的代码:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QApplication>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QtMessageHandler>
#include <QThread>
#include <thread>
#include <QFontDatabase>
#include <QQmlContext>
#include <QQuickImageProvider>
#include <qDebug>
#include "base/common/utabdiag.hxx"
#include "appctrl/appctrl.hxx"
#include "base/appctrl/appsettings.hxx"
QFile* debugFile = NULL;
//图标图片提供者
class IconImageProvider : public QQuickImageProvider
{
public:
IconImageProvider()
: QQuickImageProvider(QQuickImageProvider::Pixmap)
{
}
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
int width = 96;
int height = 96;
if (size)
*size = QSize(width, height);
QString path = id;
//qDebug()<<size->width()<<size->height()<<"....IconImageProvider"<<id;
QPixmap pixmap(path);
return pixmap;
}
};
//初始化日志输出
void initDebug()
{
QDateTime dateTimer = dateTimer.currentDateTime();
QString beday = dateTimer.addDays(-3).toString("yyyy-MM-dd");
QString cacheDir = QCoreApplication::applicationDirPath();
cacheDir = cacheDir +"/log_file";
QDir dir(cacheDir);
foreach(QFileInfo mfi ,dir.entryInfoList())
{
if(mfi.isFile())
{
QString cuDay = mfi.created().toString("yyyy-MM-dd");
if(cuDay > beday)
{
}else
{
QFile lastfile(cacheDir +"/" + mfi.fileName());
lastfile.remove();
}
}else
{
if(mfi.fileName()=="." || mfi.fileName() == "..")continue;
}
}
QDir d;
d.mkdir(cacheDir);
QString cur_dateTime= dateTimer.toString("yyyy-MM-dd_hh-mm-ss");
QString fileName = "log_" + cur_dateTime + ".txt";
debugFile = new QFile(cacheDir + "/" +fileName);
if (!debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
delete debugFile;
debugFile = NULL;
}
}
//输出消息
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QString text;
switch(type)
{
case QtDebugMsg:
text = QString("Debug:");
break;
case QtWarningMsg:
text = QString("Warning:");
break;
case QtCriticalMsg:
text = QString("Critical:");
break;
case QtFatalMsg:
text = QString("Fatal:");
}
QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
QString current_date = QString("(%1)").arg(current_date_time);
QString message = QString("%1 %2 %3\n").arg(text).arg(current_date).arg(msg);
//
if (debugFile != NULL) {
debugFile->write(message.toUtf8());
debugFile->flush();
}
}
//输出内存计数器
void printMemCntr()
{
qInfo("the UtAbBase Mem Counter: New = %d, Malloc =%d ",
UtAb::UtAbDiag::currentMemCntr( UtAb::UtAbDiag::MemCntrType_New ),
UtAb::UtAbDiag::currentMemCntr( UtAb::UtAbDiag::MemCntrType_Malloc )
);
}
//注册qml类型
void regTypes( )
{
//qmlRegisterUncreatableType<UtAbPatient::PatientVm>("utabpatient.viewmodel", 1, 0, "PatientVm", g_cpp_note );
//qmlRegisterType<UtAbCapb::CapbCanvas>("CapbCanvas", 1, 0, "CapbCanvas");
}
// 加载字体
void loadFonts( )
{
QDir dir( QString("%1/resource").arg( QCoreApplication::applicationDirPath()));
QStringList files = dir.entryList( QStringList() << "*.ttf" );
QStringList::const_iterator c_itr = files.cbegin();
while ( c_itr != files.cend()) {
if ( QFontDatabase::addApplicationFont( QString("%1/resource/%2").arg( QCoreApplication::applicationDirPath()).arg( *c_itr )) == - 1) {
qInfo() << "load " << *c_itr << " failed!";
qDebug()<<"load";
}
++ c_itr;
}
}
int main(int argc, char *argv[])
{
int ret;
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));//虚拟键盘支持
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);//启用高Dpi缩放
QGuiApplication app(argc, argv);
//初始化输出debug
initDebug();
//输出消息安装
#ifdef QT_RELEASE_WARNINGS
qInstallMessageHandler(outputMessage);
#endif
//qml类型注册
regTypes( );
qDebug() << "current app path:" << QDir::currentPath();
qDebug( ) <<"the exe. path:" << QCoreApplication::applicationDirPath();
qDebug("before AppCtrl getInstance( ) instance.");
//输出内存计数器
printMemCntr();
//加载字体
loadFonts();
//设置程序使用字体
// if ( app_set->langCountry() == QStringLiteral("zh_CN")) {
// QApplication::setFont( QFont( QStringLiteral("WenQuanYi Micro Hei"), 16 ));
// } else {
QGuiApplication::setFont( QFont( QStringLiteral("Roboto"), 16 ));
// }
//初始化硬件设备SDK
QObject *app_ctrl = UtAbMain::AppCtrl::getInstance();
QObject *app_settings = UtAb::AppSettings::globalInstance();
//创建一个qml场景
QQmlApplicationEngine *engine = new QQmlApplicationEngine( );
engine->addImageProvider(QLatin1String("iconProvider"), new IconImageProvider);
engine->addImportPath( QString("qrc:/"));
//注册上下文
engine->rootContext()->setContextProperty("gAppSet",app_settings);
engine->rootContext()->setContextProperty("gAppCtrl", qobject_cast< QObject *>( app_ctrl ));
engine->load(QUrl(QLatin1String("qrc:/view/main.qml")));
printMemCntr();
ret = app.exec();
delete engine;
qDebug("before free AppCtrl instance.");
printMemCntr();
/*此处全局性东西是放
UtAb::DevCtl::freeInstance();
*/
qDebug("after call wait until end.");
printMemCntr();
return ret;
}