歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

基於Qt/C++的ProjectExplorer實現

我在寫MarkdownOne的時候, 需要有一個類似各大IDE都有的ProjectExplorer這樣的東西. 我需要的功能比較簡單, 就是顯示外加一些簡單操作而已. 因為自己平日裡愛極了QtCreator這個IDE, 它的ProjectExplorer是相當贊的. 於是一開始我就想反正QtCreator是插件機制的各個模塊之間應該耦合度比較低, 直接看它的源碼下一些功夫應該可以把這部分給摳出來. 但是打開QtCreator1.0的源碼看的時候, 發現比我預想的要復雜, 並不是一時半會兒就能搞定的. 還是自己寫吧, 反正要的功能也不多, 自己實現也還算簡單, 無非數據, 顯示, 操作, 這三樣還有個專業術語MVC.實現效果如下(紅色區域部分):


 

因為目錄結構其實是一個樹形結構, 那麼在顯示方面, 當屬TreeView了. 而Model呢, 自己遞歸遍歷目錄生成對應的數據, 也簡單, 但除了自己實現之外還有更簡潔的東西, Qt為我們提供了QFileSystemModel. 而在Qt裡面沒有Control的概念而是用Delegate來代替, 反正也差不多. 在這裡ProjectExplorerView, ProjectExplorerModel, ProjectExplorerItemDelegate 分別繼承於QTreeView,QFileSystemModel和QStyledItemDelegate.

在這其中, 其實ProjectExplorerView不是必須的, 因為QTreeView已經可以滿足我們的需求, 這樣做把一些內部實現放到了派生類中, 用戶不必關心這些細節, 以方便以後再其他地方重復利用, 代碼比較簡單, 不廢話了上代碼:

//ProjectExplorerView.h


#ifndef PROJECTEXPLORERVIEW_H
#define PROJECTEXPLORERVIEW_H

#include <QTreeView>

class ProjectExplorerModel;
class ProjectExplorerItemMenu;
class ProjectExplorerMenu;

class ProjectExplorerView : public QTreeView
{
 Q_OBJECT
public:
 explicit ProjectExplorerView(QWidget *parent = 0);

 /**
  * @brief setRootPath Sets the directory that is being watched by the model to newPath
  * @param path
  */
 void setRootPath(const QString &path);

signals:
 void signalDoubleClickedFile(const QString &filePath);
 void signalDoubleClickedDir(const QString &dirPath);

public slots:

protected:
 void mousePressEvent(QMouseEvent *event);

private:
 void initSetting();
 void initData();
 void initGui();

private:
 ProjectExplorerModel *pModel_;
 ProjectExplorerItemMenu *pItemMenu_;
 ProjectExplorerMenu *pMenu_;
};

#endif // PROJECTEXPLORERVIEW_H

//ProjectExplorerView.cpp

#include "ProjectExplorerView.h"

#include <QDebug>
#include <QFileInfo>
#include <QModelIndex>
#include <QMouseEvent>

#include "ProjectExplorerItemDelegate.h"
#include "ProjectExplorerModel.h"

#include "ProjectExplorerItemMenu.h"
#include "ProjectExplorerMenu.h"

ProjectExplorerView::ProjectExplorerView(QWidget *parent)
 : QTreeView(parent)
 , pModel_(NULL)
 , pItemMenu_(NULL)
 , pMenu_(NULL)
{
 initSetting();
 initData();
 initGui();
}

void ProjectExplorerView::setRootPath(const QString &path)
{
 pModel_->setRootPath(path);
 this->setRootIndex(pModel_->index(path));
}

void ProjectExplorerView::mousePressEvent(QMouseEvent *event)
{
 if(event->buttons() == Qt::RightButton)
 {
  QModelIndex index = indexAt(event->pos());
  if(!index.isValid())
  {
  qDebug() << "點了空白處";
  pMenu_->move(event->globalPos());
  pMenu_->show();
  }
  else
  {
  pItemMenu_->move(event->globalPos());
  qDebug() << pModel_->fileName(index);
  pItemMenu_->show();
  }

  event->accept();
  return;
 }

 event->ignore();
 return QTreeView::mousePressEvent(event);
}

void ProjectExplorerView::initSetting()
{
 //this->setAccessibleName("Name");
 //按鍵響應編輯
 this->setEditTriggers(QAbstractItemView::EditKeyPressed);//只響應鍵盤的編輯事件
 //this->setContextMenuPolicy(Qt::CustomContextMenu);
}

void ProjectExplorerView::initData()
{
 pModel_ = new ProjectExplorerModel(this);
 this->setModel(pModel_);
 connect(this, &ProjectExplorerView::doubleClicked, [=](const QModelIndex &index){
  QString path = pModel_->filePath(index);
  QFileInfo info(path);
  if(info.isDir())
  {
  Q_EMIT signalDoubleClickedDir(path);
  }
  else if(info.isFile())
  {
  Q_EMIT signalDoubleClickedFile(path);
  }
  else if(info.isSymLink())
  {
  QString source = info.symLinkTarget();
  qDebug() << "這個快捷方式是? " << source;

  }
  else
  {
  qDebug() << "這是毛? " << info.path();
  }
 });

 pMenu_ = new ProjectExplorerMenu(this);
 pItemMenu_ = new ProjectExplorerItemMenu(this);

 this->setItemDelegate(new ProjectExplorerItemDelegate());
}

void ProjectExplorerView::initGui()
{

}

或許一些也學Qt的小伙伴看到這一串代碼中connect那一部分有點懵

connect(this, &ProjectExplorerView::doubleClicked, [=](const QModelIndex &index){
  QString path = pModel_->filePath(index);
  QFileInfo info(path);
  if(info.isDir())
  {
  Q_EMIT signalDoubleClickedDir(path);
  }
  else if(info.isFile())
  {
  Q_EMIT signalDoubleClickedFile(path);
  }
  else if(info.isSymLink())
  {
  QString source = info.symLinkTarget();
  qDebug() << "這個快捷方式是? " << source;

  }
  else
  {
  qDebug() << "這是毛? " << info.path();
  }
 });

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-12/93366p2.htm

Qt 的詳細介紹:請點這裡
Qt 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved