深度文件管理器技术填坑日记

dragonson520

dragonson520

发表于 2017-01-10 16:51:22
内容来源: 网络

单例模板设计

c++里面我们经常使用单例对象,特别是在做全局对象的时候,我们希望程序里边就只有一个单例。实现一个单例的程序例如下面:

class A{
    public:
    static A* instance{
        static A instance;
        return &insance;
    }
    private:
    A();
    ~A();
    A(const A &);
    A & operator = (const A &);
}

但是在一个项目里边我们有很多个单例对象,那岂不是每个类都要写一遍实例化函数?我们可以做一个单例模板:


template<typename T>
class Singleton
{
public:
    static T* instance(){
        static T instance;
        return &instance;
    }

private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton &);
    Singleton & operator = (const Singleton &);
};

这时候我们就可以初始化各种类的全局单例对象了:

#define globalA Singleton<A>::instance()
#define globalB Singleton<B>::instance()
globalA;
globalB;

对于这样的模板单例,我感觉能让代码更加规范,可读性也比较好,在这记录下来了。

单进程多窗口管理

文件管理器是一个但进程多窗口应用。所谓但进程多窗口,就是不管打开了多少个应用窗口,它其实都是在一个独立进程里边,在打开新窗口的时候我们并没有因此开辟了一个新进程。多窗口实现还是蛮简单的,但进程就针对不同平台有不同的解决办法(windows,linux的解决方法都有不同)这里主要针对linux下如何实现单例应用。在linux下要实现单例应用,方法有挺多的,然而有些方法是不怎么靠谱(特别使用QSharedMemery来实现单例应用时候,在程序正常运行的时候加锁是正常的,正常退出程序的时候解锁也是正常的,但是直接杀掉这个进程,就没法解锁了,后面就不能正常启动程序了)不管怎么样,这里列下两种暂时没发现有问题的方式实现单例应用:

   1. 通过QLocalSocket/QLocalServer监听服务连接(windows,linux都适用)

使用QLocalSocket/QLocalServer实现一个单例应用实现的过程如上图结构。我们来一步步讲解它的逻辑是怎么走的。按着这个结构,我们首先在启动程序之前,先用QLocalSocket跟服务端进行连接,如果连接失败了,这时候证明当前的进程就是唯一的单例。然后我们用QLocalServer去监听我们规定好的地址,等待这下一个同样的进程启动的时候接受发送过来的数据进行命令处理;如果连接成功了,证明系统已经有了一个单例进程,我们通过对Server端写命令数据(这个数据是自定义的,这样我们就可以跟单例进程通讯,让创建新窗口,而不是开一个新进程来创建新窗口),然后退出该进程。如此循环,不管我们启动多少次程序,都只有一个进程在跑着啦!

接下来我们看一下QLocalSocket/QLocalServer做了什么。首先QLocalServer监听服务,它的地址名字是自定义的,比如我们的文件管理器地址叫做dde-file-manager,然后它会在XDG_RUNTIME_DIR里边创建了一个地址名字文件(如果已经有了就略过),然后在这个地址上监听sokect请求。接着是QLocalSocket连接服务,地址也是这个自定义的名字,如果有服务监听这个地址,那么Socket是能够正常建立连接的,如果没有,连接将会失败。我们看一下目录截图:

(昨晚太困睡着了,今天继续写)

当程单例程序退出来了,那么我们的QLocalServer监听将会被释放内存,这时候并不会造成像QsharedMemery那样造成假锁的问题。

   2. 通过DBus服务进程监听(只使用于Linux系统)

一个Qt 的MVC构架模式

由于文件管理器这个项目有点庞大,我感觉在于MVC构架方面有点混,不好抽出来分析。这里就用个人的方法去实现了。

Controller View MenuAction 框架

基于Qt的信号-槽机制,其实我们可以很灵活地把前端和后端进行数据分离。但是过度的使用这个框架的构建代码结构,在用于高复杂的的程序设计中还是有缺陷的。因为在复杂程序中我们经常会遇到某个模块跟某个模块是有比较大的依赖关系,然而过度的把它们分离出来,这样在后期维护或者扩展的时候就比较困难了。这里的代码例子实现先留空,后面再填上去。

Entity component system 设计模式

右键菜单自动化,Qt元对象特性(路由设计)

Qt的Meta-Object-System 的功能好像都是不是很大收到关注,然而它这个特性给我们做程序开发提供了非常大的帮助。下面根据Qt官方文档的解释说明Qt 元对象系统的概念。

Qt的元对象系统系统为内部对象之间的通讯,运行时类型信息和动态属性系统提供了一套信号-槽机制。Qt的元对象系统基于三件事情:
1. Object 提供了一个使用元对象系统的基础功能类。

  1. 在类的私有区使用Q_OBJECT宏来使能元对象系统的功能,比如动态属性,信号-槽等。

  2. Meta-Object Compiler (moc) 在编译过程中把所有基础QObject类的对象进行预编译,生成元对象功能所需的代码块。

这是Qt元对象从声明实例化到编译的三个要点,当然我们在编码的时候基本不需要关系moc这块干了什么,我们只需关系怎么灵活使用qt元对象系统。我们在使用Qt库的时候应该已经很成熟的使用信号-槽机制来做业务逻辑处理了这里主要介绍后面两个特性的使用(动态属性和运行时类型信息)。

Qt属性系统

QMetaObject

QMetaEnum

dbus服务

文件系统监听实现

samba文件共享

rlocate快速文件搜索实现

缩略图生成与管理

网络文件系统

提权实现

插件机制实现

文件获取图标实现

avfs直读技术引入

格式化工具实现

无线分享(后期)

手机助手(后期)

文件管理器hack小技术

内容来源:https://segmentfault.com/a/1190000008063961

用户评论
开源开发学习小组列表