快捷搜索:  汽车  科技

qt表格控件操作(Qt制作桌面小控件-待办列表)

qt表格控件操作(Qt制作桌面小控件-待办列表)//初始化列表 void J_ToDoList::initTableView() { m_pTableView = new QTableView(this); m_pTableView->setObjectName("todo_TableView"); m_pTableView->setCursor(Qt::ArrowCursor); m_pModel = new QStandardItemModel; m_pModel->setColumnCount(1); m_pTableView->setModel(m_pModel); m_pTableView->horizontalHeader()->setVisible(false); m_pTableView->horiz

qt表格控件操作(Qt制作桌面小控件-待办列表)(1)

前言

千呼万唤始出来,QT组件库终于迎来了它的第一个小组件——待办列表。之所以编写这个组件,是因为感觉很多工作或学习中的朋友需要,可能你们已经在使用一些类似功能的软件,来帮助自己记录事项和规划时间。但是我根据自己平常的工作体会和自己的使用需求,完成了今天要分享的这个待办列表,主要设计理念就是简单、方便、快捷,主要功能包括添加、修改、删除、清空事项、标记为已完成和自动保存。其实本来还计划实现全局热键和提醒功能的,但是全局热键还是打算后面单独用一篇文章来讲解,因为它在不同平台的实现不同。而提醒功能需要设置时间,时间控件后面我也要自定义,所以这里就不使用QDateTimeEdit来实现了,这两个功能暂且先放一下,现在先来看一下实现效果:

添加事项:

qt表格控件操作(Qt制作桌面小控件-待办列表)(2)

删除事项:

qt表格控件操作(Qt制作桌面小控件-待办列表)(3)

缩放、移动和清空事项:

qt表格控件操作(Qt制作桌面小控件-待办列表)(4)

标记完成状态:

qt表格控件操作(Qt制作桌面小控件-待办列表)(5)

自动保存:

每次操作完成后都会进行自动保存,所以不必担心会有信息丢失。

qt表格控件操作(Qt制作桌面小控件-待办列表)(6)

实现方法

首先整个窗口都是基于自己封装的无边框窗口类,主界面用的也是这个类,窗口和标题栏的背景色都可以通过封装好的接口进行修改,这个在前面的文章中都介绍过。下面的待办列表其实就是一个QTableView,然后通过qss设置了一些自定义样式,本来还打算使用自定义模型的,后来觉得既然默认的QStandardItemModel就能实现基本的功能了,就没再费那功夫。列表初始化及qss样式设置实现如下:

//初始化列表 void J_ToDoList::initTableView() { m_pTableView = new QTableView(this); m_pTableView->setObjectName("todo_TableView"); m_pTableView->setCursor(Qt::ArrowCursor); m_pModel = new QStandardItemModel; m_pModel->setColumnCount(1); m_pTableView->setModel(m_pModel); m_pTableView->horizontalHeader()->setVisible(false); m_pTableView->horizontalHeader()->setStretchLastSection(true); m_pTableView->verticalHeader()->setVisible(false); m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_pTableView SIGNAL(customContextMenuRequested(const QPoint &)) this SLOT(showMenu(const QPoint &))); connect(m_pModel SIGNAL(itemChanged(QStandardItem*)) this SLOT(saveToFile())); }

QTableView#todo_TableView { background-color: rgba(255 255 255 80%); min-height: 150px; border: 0px; } QTableView:item:hover { color: black; background-color: #FFA500; } QTableView:item:selected { color: black; background-color: #FFA500; }

不同类型的事项通过不同的颜色来区分,设置QTableView中某个节点颜色的方法如下:

m_pModel->item(nRow 0)->setForeground(QBrush(QColor("#FF0000")));

当事项被标记为完成时,该节点中的文字会被加上删除线,QT中给文字加删除线的方法有多种,这里我们只介绍一种,即利用Qfont类进行实现:

QFont font("Microsoft YaHei" 10 QFont::Bold false);//设置字体、字号、加粗、斜体 font.setStrikeOut(true);//设置删除线 m_pModel->item(nRow 0)->setData(font Qt::FontRole);//设置字体

当模型发生变化时,会发射itemChanged()信号,自动保存功能就是在接收到该信号时对修改进行保存,但是这样做有个缺陷,就是删除节点或清空列表的时候,不会发射该信号,因此删除和清空操作后要再调用一次保存函数。

qt表格控件操作(Qt制作桌面小控件-待办列表)(7)

源码

整个待办列表的完整代码如下,大家如果感兴趣的话,可以参考一下:

#ifndef J_TODOLIST_H #define J_TODOLIST_H #include "MyFramelessWidget.h" #include <QTableView> #include <QStandardItemModel> #include <QVector> typedef struct { int nType; //事项类型 bool bIsMark; //是否标记完成 }TODO_TYPE; class J_ToDoList : public MyFramelessWidget { Q_OBJECT public: explicit J_ToDoList(MyFramelessWidget *parent = nullptr); void initTableView(); //初始化列表 public slots: void showMenu(const QPoint &pos); //显示右键菜单 void add(); //添加待办事项 void addProject(); //项目工作类别 void addMaintenance(); //维护工作类别 void addDaily(); //日常工作类别 void addPersonal(); //个人私事类别 void setEditOn(); //设置item处于编辑状态 void remove(); //删除待办事项 void clear(); //清空待办事项 void setMark(); //标记已完成 void removeMark(); //标记未完成 void readFromFile(); //从配置文件读取保存事项 void saveToFile(); //保存配置到本地文件; private: QTableView * m_pTableView; QStandardItemModel * m_pModel; bool m_bSaveFlag; //是否保存文件标记 QVector<TODO_TYPE> m_qVector; }; #endif // J_TODOLIST_H

#include "J_ToDoList.h" #include <QVBoxLayout> #include <QHeaderView> #include <QMenu> #include <QMap> #include <QSettings> #include <QApplication> #include <QTextCodec> #include <QDebug> J_ToDoList::J_ToDoList(MyFramelessWidget *parent) : MyFramelessWidget(parent) { this->resize(350 600); this->setAttribute(Qt::WA_DeleteOnClose); this->titleLogo_Label->setPixmap(QPixmap(":/Images/ToDoList.png")); initTableView(); QVBoxLayout *pVLayout = new QVBoxLayout; pVLayout->setMargin(0); pVLayout->setSpacing(0); pVLayout->addWidget(m_pTableView); this->central_Widget->setLayout(pVLayout); setWidgetModal(false); setWidgetOpacity(0.7); setTitleBarStyle("QWidget#titleBar_MyFramelessWidget {" "background: rgb(255 255 255); " "min-height: 25px; " "max-height: 25px; }"); //54 54 54 m_qVector.clear(); readFromFile(); } //初始化列表 void J_ToDoList::initTableView() { m_pTableView = new QTableView(this); m_pTableView->setObjectName("todo_TableView"); //m_pTableView->setMouseTracking(true); m_pTableView->setCursor(Qt::ArrowCursor); m_pModel = new QStandardItemModel; m_pModel->setColumnCount(1); m_pTableView->horizontalHeader()->setVisible(false); m_pTableView->horizontalHeader()->setStretchLastSection(true); m_pTableView->verticalHeader()->setVisible(false); m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); //m_pTableView->setFocusPolicy(Qt::NoFocus); m_pTableView->setModel(m_pModel); // m_pTableView->setStyleSheet("QTableView#todo_TableView {" // "background-color: rgba(54 54 54 80%);" // "border: 0px; }"); m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_pTableView SIGNAL(customContextMenuRequested(const QPoint &)) this SLOT(showMenu(const QPoint &))); connect(m_pModel SIGNAL(itemChanged(QStandardItem*)) this SLOT(saveToFile())); } //显示右键菜单 void J_ToDoList::showMenu(const QPoint &pos) { QMenu menu; QMenu childMenu("添加事项"); childMenu.addAction("项目" this SLOT(addProject())); childMenu.addAction("维护" this SLOT(addMaintenance())); childMenu.addAction("日常" this SLOT(addDaily())); childMenu.addAction("个人" this SLOT(addPersonal())); menu.addMenu(&childMenu); menu.addAction("删除事项" this SLOT(remove())); menu.addAction("清空事项" this SLOT(clear())); menu.addSeparator(); menu.addAction("标记已完成" this SLOT(setMark())); menu.addAction("标记未完成" this SLOT(removeMark())); menu.exec(QCursor::pos()); } //添加待办事项 void J_ToDoList::add() { QStandardItem *item = new QStandardItem(""); QPixmap pixmap(":/Images/ToDo.png"); pixmap = pixmap.scaled(24 24 Qt::KeepAspectRatio); item->setData(pixmap Qt::DecorationRole);//设置图标 item->setData(item->text() Qt::ToolTipRole);//设置提示 item->setData(QFont("Microsoft YaHei" 10 QFont::Bold false) Qt::FontRole);//设置字体 m_pModel->setItem(m_pModel->rowCount() 0 item); } //添加项目待办事项 void J_ToDoList::addProject() { TODO_TYPE todo; todo.nType = 1; todo.bIsMark = false; m_qVector.append(todo); add(); m_pModel->item(m_pModel->rowCount()-1 0)->setForeground(QBrush(QColor("#FF0000"))); setEditOn(); } //添加维护待办事项 void J_ToDoList::addMaintenance() { TODO_TYPE todo; todo.nType = 2; todo.bIsMark = false; m_qVector.append(todo); add(); m_pModel->item(m_pModel->rowCount()-1 0)->setForeground(QBrush(QColor("#336600"))); setEditOn(); } //添加日常待办事项 void J_ToDoList::addDaily() { TODO_TYPE todo; todo.nType = 3; todo.bIsMark = false; m_qVector.append(todo); add(); m_pModel->item(m_pModel->rowCount()-1 0)->setForeground(QBrush(QColor("#FF6600"))); setEditOn(); } //添加个人待办事项 void J_ToDoList::addPersonal() { TODO_TYPE todo; todo.nType = 4; todo.bIsMark = false; m_qVector.append(todo); add(); m_pModel->item(m_pModel->rowCount()-1 0)->setForeground(QBrush(QColor("#0066FF"))); setEditOn(); } //设置item处于编辑状态 void J_ToDoList::setEditOn() { if (!m_bSaveFlag) return; QStandardItem *item = m_pModel->item(m_pModel->rowCount()-1 0); QModelIndex index = item->index(); m_pTableView->edit(index); } //删除待办事项,支持多行删除 void J_ToDoList::remove() { QItemSelectionModel *selections = m_pTableView->selectionModel(); QModelIndexList selected = selections->selectedIndexes(); QMap<int int> rowMap; foreach (QModelIndex index selected) rowMap.insert(index.row() 0); int rowToDel; QMapIterator<int int> rowMapIterator(rowMap); rowMapIterator.toBack(); while (rowMapIterator.hasprevious()) { rowMapIterator.previous(); rowToDel = rowMapIterator.key(); m_pModel->removeRow(rowToDel); m_qVector.erase(m_qVector.begin() rowToDel); } saveToFile(); //删除和清空不会发送itemChanged信号,需要手动调用 } //清空待办事项 void J_ToDoList::clear() { m_pModel->clear(); m_qVector.clear(); saveToFile(); //删除和清空不会发送itemChanged信号,需要手动调用 } //标记已完成 void J_ToDoList::setMark() { m_bSaveFlag = false; //标记完成的时候也会改变model,此时不应该进行文件的保存操作 QItemSelectionModel *selections = m_pTableView->selectionModel(); QModelIndexList selected = selections->selectedIndexes(); QMap<int int> rowMap; foreach (QModelIndex index selected) rowMap.insert(index.row() 0); int rowToDel; QMapIterator<int int> rowMapIterator(rowMap); rowMapIterator.toBack(); while (rowMapIterator.hasPrevious()) { rowMapIterator.previous(); rowToDel = rowMapIterator.key(); QStandardItem *item = m_pModel->item(rowToDel 0); item->setData(item->text() Qt::DisplayRole); QFont font("Microsoft YaHei" 10 QFont::Bold false); font.setStrikeOut(true); item->setData(font Qt::FontRole);//设置字体 m_qVector[rowToDel].bIsMark = true; } m_bSaveFlag = true; saveToFile(); //删除和清空不会发送itemChanged信号,需要手动调用 } //标记未完成 void J_ToDoList::removeMark() { m_bSaveFlag = false; //标记未完成的时候也会改变model,此时不应该进行文件的保存操作 QItemSelectionModel *selections = m_pTableView->selectionModel(); QModelIndexList selected = selections->selectedIndexes(); QMap<int int> rowMap; foreach (QModelIndex index selected) rowMap.insert(index.row() 0); int rowToDel; QMapIterator<int int> rowMapIterator(rowMap); rowMapIterator.toBack(); while (rowMapIterator.hasPrevious()) { rowMapIterator.previous(); rowToDel = rowMapIterator.key(); QStandardItem *item = m_pModel->item(rowToDel 0); item->setData(item->text() Qt::DisplayRole); QFont font("Microsoft YaHei" 10 QFont::Bold false); item->setData(font Qt::FontRole);//设置字体 m_qVector[rowToDel].bIsMark = false; qDebug() << rowToDel << ": " << m_qVector[rowToDel].bIsMark; } m_bSaveFlag = true; saveToFile(); //删除和清空不会发送itemChanged信号,需要手动调用 } //从配置文件读取保存事项 void J_ToDoList::readFromFile() { m_bSaveFlag = false; //读取文件的时候也会改变model,此时不应该进行文件的保存操作 QString strPath = qApp->applicationDirPath(); strPath = "/../sys/ToDoList.ini"; QSettings settings(strPath QSettings::IniFormat); settings.setIniCodec(QTextCodec::codecForName("system")); int nCount = settings.value("ToDoList/Count" 0).toInt(); QString strNote strType strMark strContent; int nType; bool bMark; for (int i=0; i<nCount; i ) { strNote = "ToDoList/Note" QString::number(i); strType = "ToDoList/Type" QString::number(i); strMark = "ToDoList/Mark" QString::number(i); strContent = settings.value(strNote "").toString(); nType = settings.value(strType -1).toInt(); bMark = settings.value(strMark 0).toBool(); switch (nType) { case 1: addProject(); break; case 2: addMaintenance(); break; case 3: addDaily(); break; case 4: addPersonal(); break; default: addPersonal(); break; } m_qVector[m_qVector.count()-1].bIsMark = bMark; QStandardItem *item = m_pModel->item(m_pModel->rowCount()-1 0); item->setData(strContent Qt::DisplayRole); QFont font("Microsoft YaHei" 10 QFont::Bold false); if (bMark) font.setStrikeOut(true); item->setData(font Qt::FontRole);//设置字体 } m_bSaveFlag = true; } //保存配置到本地文件 void J_ToDoList::saveToFile() { if (!m_bSaveFlag) return; QString strPath = qApp->applicationDirPath(); strPath = "/../sys/ToDoList.ini"; QSettings settings(strPath QSettings::IniFormat); settings.setIniCodec(QTextCodec::codecForName("system")); settings.clear(); settings.setValue("ToDoList/Count" m_pModel->rowCount()); QString strNote strType strMark; for (int i=0; i<m_pModel->rowCount(); i ) { strNote = "ToDoList/Note" QString::number(i); strType = "ToDoList/Type" QString::number(i); strMark = "ToDoList/Mark" QString::number(i); settings.setValue(strNote m_pModel->item(i 0)->text()); settings.setValue(strType m_qVector[i].nType); qDebug() << i << ": " << m_qVector[i].bIsMark; settings.setValue(strMark m_qVector[i].bIsMark); } }

qt表格控件操作(Qt制作桌面小控件-待办列表)(8)

猜您喜欢: