阅读Qt Creator-OutputPane相关

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

image

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

image

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

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相关的代码。this

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

1. OutputPaneManager::create()

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

2. registerDefaultContainers() 和 registerDefaultActions()

用于添加主窗口的菜单,具体添加方法参见http://www.devbean.info/2012/03/qtcreator-plugin-develop-catalog/设计

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)中。

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

相关文章
相关标签/搜索