博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阅读Qt Creator-OutputPane相关
阅读量:6101 次
发布时间:2019-06-20

本文共 5484 字,大约阅读时间需要 18 分钟。

hot3.png

这里主要分析QtCreator中OutputPane的相关内容,可以看到QtCreator在状态栏有四个Checkable按钮,如下图所示

checkable按钮的实现方式基本一致,这里仅以其中一种General Message来说明问题。在插件源码的coreplugin中,相关类有ModeManager,MessageManager,MessageOutputWindow,OutputPaneManager,OutputPaneToggleButton,OutputPaneManageButton,OutputPanePlaceHolder,MiniSplitterHandle,OutputWindow以及StatusBarManager和StatusBarWidget。这里首先看一下他们之间的关系。

接下来详细解释与分析一下(高手勿喷,请多指教)。微笑

MainWindow的构造函数都做了些什么?

MainWindow应该做的都只是各种管理器的初始化工作,如何布局是由ModeManager来管理的,ModeManager通过各个不同的Mode来呈现不同的界面布局。

IMode就是这些Mode的接口类,在后面会详细介绍。先看MainWindow,初始化分为了三个部分:构造函数、init()、extensionsInitialized()。在Qt Creator中,很多Manager使用单例模式,但是这些单例模式可以说是一种不自动的,没有根据成员m_instance的状态来判断是创建实例还是直接返回,每一个Manager都需要create一下(好处不详,没有分析出来悲伤,望高手赐教)。在构造函数中就是调用这些create(),合情合理,构造函数不就是创建嘛。先上段代码看看:

 

MainWindow::MainWindow() :    Utils::AppMainWindow(),    m_coreImpl(new ICore(this)),    .....    m_actionManager(new ActionManager(this)),    m_editorManager(0),    .....    m_statusBarManager(0),    m_modeManager(0),    .....    m_activeContext(0),    m_generalSettings(new GeneralSettings),    m_shortcutSettings(new ShortcutSettings),    .....    m_toggleSideBarAction(0),	.....    m_toggleSideBarButton(new QToolButton){    (void) new DocumentManager(this);    OutputPaneManager::create();    setWindowTitle(tr("Qt Creator"));	......	......    registerDefaultContainers();    registerDefaultActions();    ......    m_modeStack = new FancyTabWidget(this);    m_modeManager = new ModeManager(this, m_modeStack);    m_modeManager->addWidget(m_progressManager->progressView());    m_statusBarManager = new StatusBarManager(this);    m_messageManager = new MessageManager;    m_editorManager = new EditorManager(this);    m_editorManager->hide();    m_externalToolManager = new ExternalToolManager();    setCentralWidget(m_modeStack);    .......    statusBar()->insertPermanentWidget(0, m_toggleSideBarButton);		.......}

撇掉与输出窗口无关的东西,上面的代码就是与Output相关的代码。

m_actionManager用于管理菜单,关于Output仅用于注册快捷键。

1. OutputPaneManager::create()

完成OutputPaneManager创建,在其构造函数中添加了“清除action”,“prevAction”,“nextAction”,”最大化最小化”,”关闭“等输出窗口上toolbar的一些action。这几个action是所有输出类窗口的公共action,也就是说,所有的输出类窗口都会有这几个action。

2. registerDefaultContainers() 和 registerDefaultActions()

用于添加主窗口的菜单,具体添加方法参见

3.new FancyTabWidget 和 new ModeManager

FancyTabWidget是Qt Creator窗口最左边的一列,包括欢迎、编辑、调试、设计、项目、分析、帮助,下边还有一个大家都熟悉的cornerWidget(放着构建、构建运行等几个按钮)。ModeManager用于管理各种Mode,比如EditMode,WelcomeMode等等,每一个FancyTabWidget中的Tab对应一个Mode,从这里可以看出,可以通过添加IMode的子类以在FancyTabWidget中添加Tab。ModeManager的构造函数完成FancyTabWidget的Tab改变所引起的信号的槽,并添加cornerWidget(在FancyTabWidget中,并没有添加,只是添加了一个占位的布局而已)。

4. new StatusBarManager(this) 和 new MessageManager

StatusBarManager的构造函数完成根据StatusBarWidget的个数(四个)向StatusBar添加Widget的功能(其实就相当于将状态栏分成了四个部分),并将他们存放在QList<QWidget*>中以便以后使用。来一段代码

StatusBarManager::StatusBarManager(MainWindow *mainWnd)  : QObject(mainWnd),    m_mainWnd(mainWnd){    for (int i = 0; i <= StatusBarWidget::Last; ++i) {        QWidget *w = new QWidget();        m_mainWnd->statusBar()->insertPermanentWidget(i, w);        w->setLayout(new QHBoxLayout);        w->setVisible(true);        w->layout()->setMargin(0);        m_statusBarWidgets.append(w);    }    m_mainWnd->statusBar()->insertPermanentWidget(StatusBarWidget::Last+1,                                                  new QLabel(), 1);}

个人认为这里使得状态栏的分组个数固定,设计并不是很好,插件希望添加按钮到状态栏时就遇到了困难,需要修改StatusBarWidget,并重新编译Core插件,不知道是我理解的不够深入还是怎么转动眼睛。MessageManager的构造函数并没有做什么实质性的东西。

statusBar()->insertPermanentWidget(0, m_toggleSideBarButton);在状态栏的最左边添加了一个按钮用于显示/隐藏边栏。

MainWindow的init()做了些什么?

先上代码,已经去掉无关代码。

bool MainWindow::init(QString *errorMessage){    Q_UNUSED(errorMessage)    .....    ExtensionSystem::PluginManager::addObject(m_coreImpl);    m_statusBarManager->init();    m_modeManager->init();    .......    m_outputView = new Core::StatusBarWidget;    m_outputView->setWidget(OutputPaneManager::instance()->buttonsWidget());    m_outputView->setPosition(Core::StatusBarWidget::Second);    ExtensionSystem::PluginManager::addObject(m_outputView);    m_messageManager->init();    return true;}

1. m_statusBarManager->init()

仅将对象池的objectAdded() 和aboutToRemoveObject()两个信号关联到了相应的槽函数objectAdded(QObject*)和aboutToRemoveObject(QObject*)。当有对象添加到对象池当中时,就使用Aggregation来查询是否是StatusBarWidget类型,如果是该类型,就将相对应的Widget添加到状态栏的相应位置当中,并添加到窗口列表(QMap<QWidget *, IContext *> m_contextWidgets)当中。aboutToRemoveObject就是从窗口列表中删除。

2. m_modeManager->init()

与StatusBarManager一样,仅将对象池的objectAdded() 和aboutToRemoveObject()两个信号关联到了相应的槽函数objectAdded(QObject*)和aboutToRemoveObject(QObject*)。他查询的是IMode类型,如果是IMode类型,就将其添加到FancyTabWidget当中,并链接相应的槽,注册快捷键。

3.new Core::StatusBarWidget()之后的几句代码

创建了一个Widget,这个Widget由OutputPaneManager来负责填充,并设置这个widget放在状态栏的第2个位置上(有4个位置),添加这个StatusBarWidget到对象池,相应的槽函数完成真正的插入工作。

4. MessageManager::init()

该函数中创建MessageOutputWindow,并将其添加到对象池中。

MainWindow的extensionsInitialized()都做了些什么?

简要代码如下:

void MainWindow::extensionsInitialized(){    .......    m_statusBarManager->extensionsInitalized();    OutputPaneManager::instance()->init();    .......    // reading the shortcut settings must be done after all shortcuts have been registered    m_actionManager->d->initialize();    .......}

1. m_statusBarManager->extensionsInitalized()

该函数为空,可以进行扩展。

2. OutputPaneManager::instance()->init()

首先在主窗口的menuBar中添加菜单,关联”清空“,”最大化/最小化“操作。然后从对象池当中得到所有的IOutputPane,并将它们根据在状态栏中的位置进行排序。然后将每个IOutputPane的输出窗口outputWidget添加到QStackedWidget当中,将toolBarWidget添加到输出窗口上边的工具栏m_opToolBarWidgets(也是一个StackedWidget)中。

好,先写这么多,以后继续补充。

转载于:https://my.oschina.net/MichaelBJFU/blog/67514

你可能感兴趣的文章
Linux中环境变量文件及配置
查看>>
从0开始学Flutter
查看>>
mysql操作入门基础之对数据库和表的增删改查
查看>>
IIS负载均衡
查看>>
分布式事务,EventBus 解决方案:CAP【中文文档】
查看>>
Linux下的CPU性能瓶颈分析案例
查看>>
spring mvc入门
查看>>
2012在数据库技术会议上的讲话PPT打包
查看>>
【Android】 TextView设置个别字体样式
查看>>
python svn
查看>>
raise语句
查看>>
sequence2(高精度dp)
查看>>
如何向 Linux 内核上游提交 Patch ?
查看>>
Go编程笔记(7)
查看>>
Go语言int类型绑定方法
查看>>
pid控制的文章
查看>>
MySQL中EXPLAIN命令详解
查看>>
redis 单点部署
查看>>
JEPLUS报表制作——JEPLUS软件快速开发平台
查看>>
初始化Windows powershell,连接Python
查看>>