当前位置: 首页 > news >正文

pyqt qtableview 添加下拉框控件_Qt制作桌面小控件-待办列表,从此事情再多也不会忘了

a2a06ab4266242c980059b305f0269dc

前言

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

添加事项:

ff978358288e4748b4a91e050b45bb29

删除事项:

6cfa3c5b38654369970f5ec006956389

缩放、移动和清空事项:

1b8da5138e0d462687cf22008c994fba

标记完成状态:

9b8c78af3da44b689a27983d050da6a4

自动保存:

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

02f8261e1d184166954ffef355235330

实现方法

首先整个窗口都是基于自己封装的无边框窗口类,主界面用的也是这个类,窗口和标题栏的背景色都可以通过封装好的接口进行修改,这个在前面的文章中都介绍过。下面的待办列表其实就是一个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()信号,自动保存功能就是在接收到该信号时对修改进行保存,但是这样做有个缺陷,就是删除节点或清空列表的时候,不会发射该信号,因此删除和清空操作后要再调用一次保存函数。

333b1ab6-49e7-4786-baf5-6945c2bfe7c4

源码

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

#ifndef J_TODOLIST_H#define J_TODOLIST_H#include "MyFramelessWidget.h"#include #include #include typedef struct{    int     nType;      //事项类型    bool    bIsMark;    //是否标记完成}TODO_TYPE;class J_ToDoList : public MyFramelessWidget{    Q_OBJECTpublic:    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          m_qVector;};#endif // J_TODOLIST_H
#include "J_ToDoList.h"#include #include #include #include #include #include #include #include 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 rowMap;    foreach (QModelIndex index, selected)        rowMap.insert(index.row(), 0);    int rowToDel;    QMapIterator 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 rowMap;    foreach (QModelIndex index, selected)        rowMap.insert(index.row(), 0);    int rowToDel;    QMapIterator 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 rowMap;    foreach (QModelIndex index, selected)        rowMap.insert(index.row(), 0);    int rowToDel;    QMapIterator 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; iitem(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; irowCount(); 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);    }}
71a0bb0d-5996-45bb-9745-e2884daabefb

相关文章:

  • 2018 ideal 链接数据_2018 年度 GtiHub 开源项目 TOP 25:数据科学 机器学习
  • .describe() python_Python-Win32com-Excel
  • js 点击选择前和选择后的数据对比_「手把手教python3接口自动化」:结构化数据提取...
  • gpg: 找不到有效的 openpgp 数据。_最新免费电子书网站,就没有找不到的电子书,亲测有效,赶快收藏...
  • python中的点表示什么_Python中的点表示法。方法应该在对象之前还是之后?
  • python内容推荐算法_python 推荐算法
  • 新闻类app页面使用说明书_【好物推荐】备忘录类APP“知了清单”深度使用体验...
  • grep 与条件_【命令解析】Linux系统 grep命令用法详解
  • 左斜杠和右斜杠有什么区别_优先通行权中右方来车先行,右转弯让左转弯,为什么呢?...
  • matlab lu分解求线性方程组_计算方法(三)平方根法及其改进解线性方程组
  • python chdir_Python os.chdir()用法及代码示例
  • python工业应用_python工业互联网应用实战3—模型层构建
  • python删除首行_python 删除文件首行或指定行(修改文件)
  • python蟒蛇绘制加眼睛_python蟒蛇绘制 - osc_sm6rxbzs的个人空间 - OSCHINA - 中文开源技术交流社区...
  • 4n35光耦引脚图_数字隔离器的演进推动了光耦合器的替换进程
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • bearychat的java client
  • express.js的介绍及使用
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Linux Process Manage
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • orm2 中文文档 3.1 模型属性
  • PAT A1092
  • PHP 小技巧
  • React 快速上手 - 07 前端路由 react-router
  • Transformer-XL: Unleashing the Potential of Attention Models
  • Yii源码解读-服务定位器(Service Locator)
  • 复杂数据处理
  • 强力优化Rancher k8s中国区的使用体验
  • 悄悄地说一个bug
  • 使用parted解决大于2T的磁盘分区
  • 温故知新之javascript面向对象
  • 我有几个粽子,和一个故事
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 怎样选择前端框架
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #WEB前端(HTML属性)
  • $GOPATH/go.mod exists but should not goland
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (C)一些题4
  • (笔试题)合法字符串
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (五)网络优化与超参数选择--九五小庞
  • (一)插入排序
  • (转载)Linux 多线程条件变量同步
  • .NET DataGridView数据绑定说明
  • .net framework4与其client profile版本的区别
  • .net 验证控件和javaScript的冲突问题
  • .Net(C#)自定义WinForm控件之小结篇
  • .net连接oracle数据库
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .NET上SQLite的连接