现在我们已经有一个大致的界面。 加上可视化的东西,主要目的是为了让想像的样子逐步接近最终的样子, 同时开发流程更加直观:因为看到了,可能会觉得这里不错,那里设计不好。 这样的一个折腾过程,其实也能收获很多。

好了,我们继续。

缺少什么?

在导出一个主窗口供执行模块qtMeownote调用后,我感觉仍然是缺少一些东西。

想像一下,界面打开后,通常会显示一些当前数据,比如说,笔记本视图中会显示 我最近使用的笔记,状态栏显示一些当前笔记的统计信息等。 很明显,在将这些数据呈现出来之前,它们需要先被加载进来。 这种潜在意识,就表明程序需要一个恰当的执行流程。

对于我们的笔记软件,大致如下:

当然,你可能会想,我在创建界面的时候直接加载一些数据不行么?当然可以。 但这样可能会使后面的事情复杂化,有可能A界面需要B数据,但此时B数据却依赖X数据, 而X数据此时还未加加载。

所以,不如在创建界面之前,把需要的初始化数据加载进来。 创建界面时,只需要读取即可。

当然,你也可以决定在EXE模块中初始化数据,再创建窗口。 但这样一来,EXE会依赖mnMeownote与mnComponents两个模块 与我们划分的层关系有出入,但是,这仍然是可行的。 缺点就是将应用程序的周期划分到两个不同的地方实现了。

引入App类

为了这个流程,我引入了两个Application类, 是的两个!

class mnMeownoteApp { public: mnMeownoteApp(int &argc, char **argv); ~mnMeownoteApp(); bool initialize(); void uninitialize(); int run(); }; bool mnMeownoteApp::initialize() { mnApplication *app = mnApplication::instance(); return app->init(); }

细心的你会注意到,没有数据!是的,为了让客户端知道的更少,采用一种代理策略:你要我干什么,我就让我兄弟去。很明显,我兄弟是一个单例模工。

class mnApplication : public QApplication { Q_OBJECT public: static mnApplication* instance() { return ms_instance; } mnApplication(int &argc, char **argv); ~mnApplication(); bool init(); void release(); private: void setupStyleSheet(); private: static mnApplication *ms_instance; mnMainWindow *m_mainWindow = nullptr; };

经过这两步之后,程序的程序就完全掌控于当前模块之中了。这就是引入应用程序类的目的了。我们总结一下:

样式表

Qt可以很容易的实现外观美化。注意,我说的是美化,不是说超级酷炫,那估计自绘或QML更合适。现在为了验证一下我们的流程,顺带组织一下结构,这里我给出了一个加载样式表的过程。

bool mnApplication::init() { setupStyleSheet(); m_mainWindow = new mnMainWindow(nullptr); m_mainWindow->show(); return true; } void mnApplication::setupStyleSheet() { QString defaultThemeFile = applicationDirPath() "/theme/default/default.qss"; QFile file(defaultThemeFile); file.open(QFile::ReadOnly); if (file.isOpen()) { QString sheet = QLatin1String(file.readAll()); this->setStyleSheet(sheet); file.close(); } }

到这里之后,相比于界面外观,我们的内核升级了。

qt程序基本步骤(使用Qt开发笔记软件)(1)

,