整体源码下载如下:

https://download.csdn.net/download/qq78442761/10810431

效果图如下:

源码如下:

adddialog.h

#ifndef ADDDIALOG_H
#define ADDDIALOG_H#include <QDialog>struct AddData{QString name;QString shellFilePath;
};namespace Ui {
class AddDialog;
}class AddDialog : public QDialog
{Q_OBJECTpublic:AddDialog(QWidget *parent = 0);AddData *getAddData();void setNameAndFilePath(const QString name, const QString filePath);~AddDialog();protected:void closeEvent(QCloseEvent *event);protected slots:void okBtnClicked();void selectBtnClicked();private:Ui::AddDialog *ui;AddData *m_addData;
};#endif // ADDDIALOG_H

fileoper.h

#ifndef FILEOPER_H
#define FILEOPER_H#include <QString>
#include <QVector>class FileOper
{
public:FileOper(const QString fileName);~FileOper();QVector<QString> &getContextVec();void clearContextVec();void saveFile();void readFile();private:QString m_fileName;QVector<QString> m_contextVec;
};#endif // FILEOPER_H

mydelegate.h

#ifndef MYDELEGATE_H
#define MYDELEGATE_H#include <QStyledItemDelegate>class MyDelegate : public QStyledItemDelegate
{Q_OBJECT
public:explicit MyDelegate(QWidget *parent = 0);void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const;QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;void setEditorData(QWidget *editor, const QModelIndex &index) const;void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;protected:void paint();
};#endif // MYDELEGATE_H

myonoff.h

#ifndef MYONOFF_H
#define MYONOFF_H#include <QMetaType>
#include <QRect>QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACEclass MyOnOff
{
public:enum EditMode {Editable, ReadOnly};MyOnOff(const bool isOpenStatus = false);bool getIsOpenStatus();void setIsOpenStatus(const bool isOpenStatus);void painter(QPainter *painter, const QRect &rect, const QPalette palette, EditMode mode) const;private:bool m_isOpen;
};Q_DECLARE_METATYPE(MyOnOff)#endif // MYONOFF_H

myonoffeditor.h

#ifndef MYONOFFEDITOR_H
#define MYONOFFEDITOR_H#include <QWidget>
#include "myonoff.h"class MyOnOffEditor : public QWidget
{Q_OBJECT
public:explicit MyOnOffEditor(QWidget *parent = 0);void setMyOnOffStatus(const bool myOnOffStatus);bool getMyOnOffStatus();protected:void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;private:MyOnOff m_myOnOff;
};#endif // MYONOFFEDITOR_H

mytreeview.h

#ifndef MYTREEVIEW_H
#define MYTREEVIEW_H#include <QTreeView>
#include <QVector>class MyTreeView : public QTreeView
{Q_OBJECT
public:MyTreeView(QWidget *parent = 0);void initWidget(const QVector<QString> vec);protected:void contextMenuEvent(QContextMenuEvent *event);void addItem(const QString name, const QString filePath);protected slots:void addContextMenuCalled();void removeContextMenuCalled();void doubleCilckedCalled(const QModelIndex &index);private:int m_currentSelectRow;};#endif // MYTREEVIEW_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QRect>QT_BEGIN_NAMESPACE
class QCloseEvent;
QT_END_NAMESPACEclass FileOper;namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();protected:void initWidget();void closeEvent(QCloseEvent *event);private:Ui::Widget *ui;QRect m_screenRect;FileOper *m_fileOper;
};#endif // WIDGET_H

adddialog.cpp

#include "adddialog.h"
#include "ui_adddialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>AddDialog::AddDialog(QWidget *parent) :QDialog(parent),ui(new Ui::AddDialog)
{ui->setupUi(this);m_addData = new AddData;this->setWindowTitle("添加");ui->selectShellLineEdit->setEnabled(false);connect(ui->okPushButton, SIGNAL(clicked(bool)), this, SLOT(okBtnClicked()));connect(ui->selectPushButton, SIGNAL(clicked(bool)), this, SLOT(selectBtnClicked()));
}AddData *AddDialog::getAddData()
{return m_addData;
}void AddDialog::setNameAndFilePath(const QString name, const QString filePath)
{this->setWindowTitle("编辑");ui->nameLineEdit->setText(name);ui->selectShellLineEdit->setText(filePath);
}AddDialog::~AddDialog()
{delete ui;delete m_addData;
}void AddDialog::closeEvent(QCloseEvent *event)
{Q_UNUSED(event)this->reject();
}void AddDialog::okBtnClicked(){if(ui->nameLineEdit->text().isEmpty() || ui->selectShellLineEdit->text().isEmpty()){QMessageBox::information(this, "提示", "LineEdit不能为空");return;}int btnClicked = QMessageBox::information(this, "提示", "是否确定保存?", QMessageBox::Save, QMessageBox::Cancel);if(btnClicked == QMessageBox::Save){m_addData->name = ui->nameLineEdit->text();m_addData->shellFilePath = ui->selectShellLineEdit->text();this->accept();}
}void AddDialog::selectBtnClicked()
{QString fileName = QFileDialog::getOpenFileName(this, "选择shell文件", "/home", "Shell Files(*.sh)");ui->selectShellLineEdit->setText(fileName);
}

fileoper.cpp

#include "fileoper.h"
#include <QDebug>
#include <QTextStream>
#include <QFile>FileOper::FileOper(const QString fileName)
{m_fileName = fileName;
}FileOper::~FileOper()
{qDebug()<< "~FileOper() called";
}QVector<QString> &FileOper::getContextVec()
{return m_contextVec;
}void FileOper::clearContextVec()
{m_contextVec.clear();
}void FileOper::saveFile()
{QFile file(m_fileName);if(!file.open(QFile::WriteOnly | QFile::Text)){throw "file can't open";}QTextStream out(&file);for(int i = 0; i < m_contextVec.size(); i++){out << m_contextVec[i] << "\n";}file.close();
}void FileOper::readFile()
{QFile file(m_fileName);if(!file.open(QFile::ReadOnly | QFile::Text)){throw "file open failed";}QTextStream in(&file);while(!in.atEnd()){m_contextVec << in.readLine();}file.close();
}

main.cpp

#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

mydelegate.cpp

#include "mydelegate.h"
#include "myonoff.h"
#include "myonoffeditor.h"#include <QPainter>
#include <QDebug>
#include <QTextItem>MyDelegate::MyDelegate(QWidget *parent) : QStyledItemDelegate(parent)
{}void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{if(index.column() == 1){if(option.state & QStyle::State_Selected){painter->fillRect(option.rect, option.palette.highlight());}painter->save();painter->setPen(Qt::black);painter->drawText(option.rect.x(), option.rect.y(), option.rect.width(), option.rect.height(), Qt::AlignCenter, "双击查看及修改文件路径");painter->restore();}else if(index.data().canConvert<MyOnOff>()){if(option.state & QStyle::State_Selected){painter->fillRect(option.rect, option.palette.highlight());}MyOnOff myOnOff = qvariant_cast<MyOnOff>(index.data());myOnOff.painter(painter, option.rect, option.palette, MyOnOff::ReadOnly);}else{QStyledItemDelegate::paint(painter, option, index);}
}QSize MyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{QSize size = QStyledItemDelegate::sizeHint(option, index);size.setHeight(size.height() + 12);return size;
}QWidget *MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_UNUSED(option)if(index.data().canConvert<MyOnOff>()){MyOnOffEditor *editor = new MyOnOffEditor(parent);MyOnOff myOnOff = qvariant_cast<MyOnOff>(index.data());editor->setMyOnOffStatus(myOnOff.getIsOpenStatus());return editor;}else{return NULL;}
}void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{Q_UNUSED(index)if(index.data().canConvert<MyOnOff>()){MyOnOff myOnOff = qvariant_cast<MyOnOff>(index.data());MyOnOffEditor *myOnOffEditor = qobject_cast<MyOnOffEditor*>(editor);myOnOffEditor->setMyOnOffStatus(!myOnOff.getIsOpenStatus());}else{QStyledItemDelegate::setEditorData(editor, index);}
}void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{if(index.data().canConvert<MyOnOff>()){MyOnOffEditor *myOnOffEditor = qobject_cast<MyOnOffEditor*>(editor);model->setData(index, QVariant::fromValue(MyOnOff(myOnOffEditor->getMyOnOffStatus())));}elseQStyledItemDelegate::setModelData(editor, model, index);
}

myonoff.cpp

#include "myonoff.h"
#include <QImage>
#include <QPainter>
#include <QPalette>
#include <QDebug>MyOnOff::MyOnOff(const bool isOpenStatus)
{m_isOpen = isOpenStatus;
}bool MyOnOff::getIsOpenStatus()
{return m_isOpen;
}void MyOnOff::setIsOpenStatus(const bool isOpenStatus)
{m_isOpen = isOpenStatus;
}void MyOnOff::painter(QPainter *painter, const QRect &rect, const QPalette palette, EditMode mode) const
{painter->setRenderHint(QPainter::Antialiasing, true);painter->save();if(mode == Editable){painter->setBrush(palette.highlight());}else{painter->setBrush(palette.foreground());}if(m_isOpen){painter->drawImage(rect.x() + 45, rect.y(), QImage(":/img/imgOpen.png"));}else{painter->drawImage(rect.x() + 45, rect.y(), QImage(":/img/imgClose.png"));}painter->restore();
}

myonoffeditro.cpp

#include "myonoffeditor.h"
#include <QPainter>
#include <QDebug>MyOnOffEditor::MyOnOffEditor(QWidget *parent) : QWidget(parent)
{setMouseTracking(true);setAutoFillBackground(true);
}void MyOnOffEditor::setMyOnOffStatus(const bool myOnOffStatus)
{m_myOnOff.setIsOpenStatus(myOnOffStatus);
}bool MyOnOffEditor::getMyOnOffStatus()
{return m_myOnOff.getIsOpenStatus();
}void MyOnOffEditor::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)QPainter painter(this);painter.save();m_myOnOff.painter(&painter, rect(), this->palette(), MyOnOff::Editable);painter.restore();
}

mytreeview.cpp

#include "mytreeview.h"
#include <QContextMenuEvent>
#include <QMenu>
#include <QDebug>
#include <QStandardItemModel>#include <QAbstractItemModel>
#include <QModelIndex>
#include "adddialog.h"
#include "myonoff.h"MyTreeView::MyTreeView(QWidget *parent): QTreeView(parent)
{m_currentSelectRow = -1;connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(doubleCilckedCalled(QModelIndex)));
}void MyTreeView::initWidget(const QVector<QString> vec)
{for(int i = 0; i < vec.size(); i++){QStringList nameAndPath = vec[i].split(";");addItem(nameAndPath[0], nameAndPath[1]);}
}void MyTreeView::contextMenuEvent(QContextMenuEvent *event)
{QMenu menu;menu.addAction("添加", this, SLOT(addContextMenuCalled()));static_cast<QStandardItemModel*>(model());QModelIndex index = indexAt(event->pos());if(index.isValid()){m_currentSelectRow = index.row();menu.addAction("删除", this, SLOT(removeContextMenuCalled()));}menu.exec(event->globalPos());
}void MyTreeView::addItem(const QString name, const QString filePath)
{int rowCount = model()->rowCount();static_cast<QStandardItemModel*>(model())->setItem(rowCount, 0, new QStandardItem(name));static_cast<QStandardItemModel*>(model())->setItem(rowCount, 1, new QStandardItem(filePath));QStandardItem *myOnOff = new QStandardItem;myOnOff->setData(QVariant::fromValue(MyOnOff(false)), 0);static_cast<QStandardItemModel*>(model())->setItem(rowCount, 2, myOnOff);
}void MyTreeView::addContextMenuCalled()
{AddDialog addDialog;if(addDialog.exec() == QDialog::Accepted){//qDebug()<< addDialog.getAddData()->name << "\t" <<addDialog.getAddData()->shellFilePath;addItem(addDialog.getAddData()->name, addDialog.getAddData()->shellFilePath);}}void MyTreeView::removeContextMenuCalled()
{if(m_currentSelectRow != -1){static_cast<QStandardItemModel*>(model())->removeRow(m_currentSelectRow);m_currentSelectRow = -1;}
}void MyTreeView::doubleCilckedCalled(const QModelIndex &index)
{if(index.column() == 1){QString name = static_cast<QStandardItemModel*>(model())->item(index.row(), 0)->data(0).toString();QString filePath = static_cast<QStandardItemModel*>(model())->item(index.row(), 1)->data(0).toString();AddDialog editDialog;editDialog.setNameAndFilePath(name, filePath);if(editDialog.exec() == QDialog::Accepted){QString newName = editDialog.getAddData()->name;QString newPath = editDialog.getAddData()->shellFilePath;static_cast<QStandardItemModel*>(model())->item(index.row(), 0)->setData(newName, 0);static_cast<QStandardItemModel*>(model())->item(index.row(), 1)->setData(newPath, 0);}}
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mydelegate.h"
#include "myonoff.h"
#include "fileoper.h"#include <QDesktopWidget>
#include <QVariant>
#include <QDebug>
#include <QCloseEvent>
#include <QHeaderView>
#include <QMessageBox>
#include <QStandardItemModel>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);m_fileOper = new FileOper("context.txt");m_fileOper->readFile();initWidget();
}Widget::~Widget()
{delete ui;delete m_fileOper;
}void Widget::initWidget()
{m_screenRect = QApplication::desktop()->screenGeometry();move((m_screenRect.width() - this->width())/2, (m_screenRect.height() - this->height())/2);QStringList headerLables;headerLables << "名称" << "shell文件路径" << "当前状态";QStandardItemModel *stdModel = new QStandardItemModel;stdModel->setHorizontalHeaderLabels(headerLables);ui->treeView->setModel(stdModel);ui->treeView->setEditTriggers(QAbstractItemView::DoubleClicked);ui->treeView->setItemDelegate(new MyDelegate);ui->treeView->initWidget(m_fileOper->getContextVec());ui->treeView->header()->setSectionResizeMode(1, QHeaderView::Stretch);ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Fixed);ui->treeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
}void Widget::closeEvent(QCloseEvent *event)
{int result = QMessageBox::information(this, "提示", "是否保存", QMessageBox::Ok, QMessageBox::Cancel);if(result == QMessageBox::Ok){m_fileOper->clearContextVec();for(int i = 0; i < ui->treeView->model()->rowCount(); i++){QString name = static_cast<QStandardItemModel*>(ui->treeView->model())->item(i, 0)->data(0).toString();QString path = static_cast<QStandardItemModel*>(ui->treeView->model())->item(i, 1)->data(0).toString();m_fileOper->getContextVec() << name + ";" + path;}try{m_fileOper->saveFile();qApp->exit();}catch(const char *err){qDebug()<< err;}}else if(result == QMessageBox::Cancel){qApp->exit();}else{}event->ignore();
}

Qt工作笔记-代理及自定义委托,实现开关功能相关推荐

  1. Qt工作笔记-对QItemDelegate自定义委托的理解

    关键是重写这四个函数: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QMo ...

  2. Qt工作笔记-QByteArray与自定义结构体之间的转化(可用于网络传输,以及数据回调)

    目录 理论 程序 理论 在Socket中,数据一般是char型(一般情况下,其实最好是用uchar来传输,避免莫名其妙的错误,但用char也是可以的),而在Qt里面可以使用QByteArray,这个在 ...

  3. Qt工作笔记-发送端发送Json格式的数据包,接收端解析数据包

    原理以及运行 原理是因为QJsonDocument提供了一个函数toJson 可以直接把Json数据转成QByteArray,这样就可以直接发送数据包,然后再按照常规方法解析即可,本源码中含解析内容, ...

  4. Qt工作笔记-QMainWindow自定义窗体中利用状态栏进行窗体放缩

    目录 原理 关键代码 原理 在QDialog和QWidget中一般使用重写: void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;void ...

  5. Qt工作笔记-自定义开关控件

    1.自定义开关控件: 2.点击有动画效果: 3.在动画效果中,不再响应信号: 运行截图如下: 输出响应信号: 源码如下: myonoff.h #ifndef MYONOFF_H #define MYO ...

  6. Qt工作笔记-依赖于QAbstractTableModel实现自定义TableModel

    目录 理论 源码 理论 设计模式里面有一句话叫 要依赖于抽象,不要依赖于具体. 但在Qt有些官方实例里,却依赖于具体实现某一子功能,这可以是为了方便把, 但在TableModel有一个依赖与抽象, 官 ...

  7. Qt工作笔记-自定义QSortFilterProxyModel实现多列分别过滤

    程序运行截图如下: 原理,重写QSortFilterProxyModel类中的filterAcceptsRow即可: 源码如下: mysortfilterproxymodel.h #ifndef MY ...

  8. Qt工作笔记-QTableWidget设置委托(使用QStyledItemDelegate画3只小猪)

    解析: 1.MyDelegate类为代理,给TableWidget的. 2.MyPic类用于画图 运行截图如下: 源码如下: mydelegate.h #ifndef MYDELEGATE_H #de ...

  9. Qt工作笔记-自定义菜单(右键菜单)

    所以,只要重写createWIdget()这个函数就阔以了! 把写好的界面放到这个parent里面不就阔以了! 写好的界面如下: 运行截图如下: 源码如下: mypopwidget.h #ifndef ...

最新文章

  1. java is not a enclosing class_Java Class getEnclosingClass()用法及代码示例
  2. [转载]明天的数字营销分析工具2
  3. 全网最细笔记java与kotlin的一些异同
  4. u盘安装linux启动报错,U盘安装centos7,启动报错
  5. 求你了,别再用 print 调试代码了
  6. 一代不如一代?别轻易给年轻人贴标签
  7. 2016-04-29 二分查找的面试题
  8. 如何为项目中的单个文件禁用ARC?
  9. vue 局部回到顶部_VUE回到顶部功能
  10. matlab图像的直方图,Matlab图像直方图相关函数
  11. nyoj 54-小明的存钱计划 (遍历 + 判断)
  12. 华为系统更新彻底卸载_华为手机系统更新好吗 华为手机系统更新方法
  13. 记工作的第一月--光说不练,假把式
  14. 权限管理框架实现(1)--Struts切面处理
  15. VMware 12虚拟机win7中添加摄像头
  16. 小红书2020校招数据分析笔试题卷四 解析
  17. 数据挖掘与机器学习——离群点检测之孤立森林(isolate forest)
  18. 全球最流行的手机型号、屏幕尺寸及分辨率
  19. 【Semantic Segmentation】语义分割综述
  20. 《你有多自律,就有多自由》经典总结

热门文章

  1. [转]数据库主键设计文章绘粹
  2. 如何在Ubuntu中使用root账号登录(新增Ubuntu12.04/14.04)?
  3. 准备拉琴的zskame大白菜
  4. 现在写程序要像蚊子一样WZ132
  5. 基于or1200最小sopc系统搭建(一)--搭建及仿真(DE2,DE2-70)
  6. python 之路,200行Python代码写了个打飞机游戏!
  7. c语言中width获取窗体宽度,获取屏幕宽高width(),outerWidth,innerWidth,clientWidth的区别...
  8. 圆括号匹配c语言代码,求救!!一道关于表达式圆括号匹配的经典题目
  9. GPB | 陈润生/何顺民团队发布新版SmProt数据库,提供小蛋白丰富、可靠的系统性注释...
  10. 生信宝典被分享最多的15篇文章