04-7_Qt 5.9 C++开发指南_QTreeWidget和QDockWidget

news2024/11/24 4:09:48

文章目录

  • 1. 实例功能简述
  • 2. 源码
    • 2.1 可视化UI设计
    • 2.2 mainwindow.h
    • 2.3 mainwindow.cpp

1. 实例功能简述

本节介绍 QTreeWidget、QDockWidget 的使用,以及用 QLabel 显示图片的方法。实例 samp4_8以QTreeWidget 为主要组件,创建一个照片管理器,实例运行时的界面如图 4-14 所示。

在这里插入图片描述

这个实例主要演示如下几个组件的使用方法。

  • QTreeWidget目录树组件

QTreeWidget 类是创建和管理目录树结构的类。实例使用一个 QTreeWidget 组件管理照片目录,可以添加、删除节点,每个节点设置一个自定义类型,另外,还设置了一个自定义数据,图片节点存储完整文件名,以便单击节点时显示该图片。

  • QDockWidget 停靠区域组件
    QDockWidget 是可以在QMainWindow 窗口停靠,或在桌面最上层浮动的界面组件。本实例将一个QTreeWidget 组件放置在 QDockWidget 区域上,设置其可以在主窗口的左或右侧停靠,也可以浮动。
  • QLabel组件显示图片
    右侧是一个QScrollArea 组件,ScrollArea 上面放置一个 QLabel组件,通过为 QLabel设置一个QPixmap 显示图片。通过 QPixmap 操作可进行缩放显示,包括放大、缩小、实际大小、适合宽度、适合高度等。

QTreeWidget、QDockWidget和QLabel组件详细的使用方法,请见源码或书籍

2. 源码

2.1 可视化UI设计

在这里插入图片描述

2.2 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include    <QMainWindow>
#include    <QTreeWidgetItem>
#include    <QLabel>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
//枚举类型treeItemType, 用于创建 QTreeWidgetItem 时作为节点的type, 自定义类型必须大于1000
//itTopItem 顶层节点;  itGroupItem 组节点; itImageItem 图片
    enum    treeItemType{itTopItem=1001,itGroupItem,itImageItem};

//枚举类型,表示列号
    enum    treeColNum{colItem=0, colItemType=1}; //目录树列的编号定义

    QLabel  *LabFileName;
    QPixmap curPixmap; //当前的图片
    float   pixRatio;//当前图片缩放比例

    void    iniTree();//目录树初始化
    void    addFolderItem(QTreeWidgetItem *parItem, QString dirName);//添加一个目录节点

    QString getFinalFolderName(const QString &fullPathName);//从目录全名称中获取最后的文件夹名称

    void    addImageItem(QTreeWidgetItem *parItem,QString aFilename);//添加一个图片节点

    void    displayImage(QTreeWidgetItem *item); //显示一个图片节点的图片

    void    changeItemCaption(QTreeWidgetItem *item); //遍历改变节点标题
public:

    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
//目录树当前节点变动的信号
    void on_treeFiles_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);

    void on_actAddFolder_triggered();//添加目录节点

    void on_actAddFiles_triggered();//添加图片节点

    void on_actZoomOut_triggered(); //缩小,zoom out

    void on_actZoomIn_triggered(); //放大,zoom in

    void on_actZoomFitW_triggered(); //适合宽度

    void on_actZoomFitH_triggered();//适合高度

    void on_actZoomRealSize_triggered(); //实际大小

    void on_actDeleteItem_triggered(); //删除节点

    void on_actScanItems_triggered(); //遍历节点

    void on_actDockVisible_toggled(bool arg1);

    void on_dockWidget_visibilityChanged(bool visible);

    void on_dockWidget_topLevelChanged(bool topLevel);

    void on_actDockFloat_triggered(bool checked);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

2.3 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QTreeWidgetItem>
#include    <QFileDialog>

void MainWindow::iniTree()
{ //初始化Tree
    QString    dataStr=""; // Item的Data 存储的string

    ui->treeFiles->clear();//清除目录树所有节点
    QIcon   icon;
    icon.addFile(":/images/icons/15.ico"); //设置ICON的图标

    QTreeWidgetItem*  item=new QTreeWidgetItem(MainWindow::itTopItem); //新建节点时设定类型为 itTopItem
    item->setIcon(MainWindow::colItem,icon); //设置第1列的图标
    item->setText(MainWindow::colItem,"图片文件"); //设置第1列的文字
    item->setText(MainWindow::colItemType,"type=itTopItem");  //设置第2列的文字
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    item->setCheckState(colItem,Qt::Checked);//设置为选中

    item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr)); //设置节点第1列的Qt::UserRole的Data
    ui->treeFiles->addTopLevelItem(item);//添加顶层节点
}

void MainWindow::addFolderItem(QTreeWidgetItem *parItem, QString dirName)
{//添加一个目录节点
    QIcon   icon(":/images/icons/open3.bmp");
    QString NodeText=getFinalFolderName(dirName); //从一个完整目录名称里,获得最后的文件夹名称

    QTreeWidgetItem *item; //节点
    item=new QTreeWidgetItem(MainWindow::itGroupItem); //新建节点, 设定type为 itGroupItem
    item->setIcon(colItem,icon); //设置图标
    item->setText(colItem,NodeText); //最后的文件夹名称,第1列
    item->setText(colItemType,"type=itGroupItem"); //完整目录名称,第2列
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); //设置节点选项
    item->setCheckState(colItem,Qt::Checked); //节点选中
    item->setData(colItem,Qt::UserRole,QVariant(dirName)); //设置角色为Qt::UserRole的Data,存储完整目录名称

    parItem->addChild(item); //在父节点下面添加子节点
}

QString MainWindow::getFinalFolderName(const QString &fullPathName)
{//从一个完整目录名称里,获得最后的文件夹名称
    int cnt=fullPathName.length(); //字符串长度
    int i=fullPathName.lastIndexOf("/");//  最后一次出现的位置
    QString str=fullPathName.right(cnt-i-1); //获得最后的文件夹的名称
    return str;
}

void MainWindow::addImageItem(QTreeWidgetItem *parItem, QString aFilename)
{//添加一个图片文件节点
    QIcon   icon(":/images/icons/31.ico");//ICON的图标
    QString NodeText=getFinalFolderName(aFilename); //获得最后的文件名称

    QTreeWidgetItem *item; //节点
    item=new QTreeWidgetItem(MainWindow::itImageItem); //新建节点时设定类型为 itImageItem
    item->setIcon(colItem,icon); //设置图标
    item->setText(colItem,NodeText); //最后的文件夹名称
    item->setText(colItemType,"type=itImageItem"); //完整目录名称
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); //设置节点选项
    item->setCheckState(colItem,Qt::Checked); //节点选中

    item->setData(colItem,Qt::UserRole,QVariant(aFilename)); //设置节点Qt::UserRole的Data,存储完整文件名称

    parItem->addChild(item); //在父节点下面添加子节点
}

void MainWindow::displayImage(QTreeWidgetItem *item)
{//显示图片,节点item存储的图片文件名
    QString filename=item->data(colItem,Qt::UserRole).toString();//获取节点data里存的文件名
    LabFileName->setText(filename);
    curPixmap.load(filename); //从文件载入图片
    on_actZoomFitH_triggered(); //自动适应高度显示

    ui->actZoomFitH->setEnabled(true);
    ui->actZoomFitW->setEnabled(true);
    ui->actZoomIn->setEnabled(true);
    ui->actZoomOut->setEnabled(true);
    ui->actZoomRealSize->setEnabled(true);
}

void MainWindow::changeItemCaption(QTreeWidgetItem *item)
{ //改变节点的标题文字
    QString str="*"+item->text(colItem);  //节点标题前加“*”
    item->setText(colItem,str); //设置节点标题

    if (item->childCount()>0) //如果有子节点
    for (int i=0;i<item->childCount();i++) //遍历子节点
       changeItemCaption(item->child(i));  //调用自己,可重入的函数
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    LabFileName=new QLabel("");
    ui->statusBar->addWidget(LabFileName);

    this->setCentralWidget(ui->scrollArea); //设置中心布局组件
    iniTree();//初始化目录树
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_treeFiles_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{ //当前节点选择变化时触发
    Q_UNUSED(previous);
    if  (current==NULL)
        return;

    int var=current->type();//节点的类型

    switch(var)
    {
        case  itTopItem: //顶层节点
          ui->actAddFolder->setEnabled(true);
          ui->actAddFiles->setEnabled(true);
          ui->actDeleteItem->setEnabled(false);    //顶层节点不能删除
          break;

        case  itGroupItem: //文件组节点
          ui->actAddFolder->setEnabled(true);
          ui->actAddFiles->setEnabled(true);
          ui->actDeleteItem->setEnabled(true);
          break;

        case  itImageItem: //图片文件节点
          ui->actAddFolder->setEnabled(false); //图片节点下不能添加目录节点
          ui->actAddFiles->setEnabled(true);
          ui->actDeleteItem->setEnabled(true);
          displayImage(current); //显示图片
          break;
    }
}

void MainWindow::on_actAddFolder_triggered()
{// 选择一个文件夹,作为当前节点的子节点加入
  QString dir=QFileDialog::getExistingDirectory();//选择目录
  if (!dir.isEmpty()) //选择目录名称不为空
  {
      QTreeWidgetItem* parItem=ui->treeFiles->currentItem(); //当前节点
      addFolderItem(parItem,dir);//在父节点下面添加一个组节点
  }
}

void MainWindow::on_actAddFiles_triggered()
{//添加图片文件节点
    QStringList files=QFileDialog::getOpenFileNames(this,"选择一个或多个文件","","Images(*.jpg)");//多选文件
    if (files.isEmpty()) //如果一个文件都没选
        return;

    QTreeWidgetItem *parItem,*item; //节点
    item=ui->treeFiles->currentItem(); //当前节点

    if (item->type()==itImageItem) //若当前节点是图片节点,取其父节点作为父节点
       parItem=item->parent();
    else //否则取当前节点为父节点
       parItem=item;

    for (int i = 0; i < files.size(); ++i)
    {
        QString aFilename=files.at(i); //得到StringList里的一行,也就是一个文件名
        addImageItem(parItem,aFilename); //添加一个图片节点
    }
}


void MainWindow::on_actZoomOut_triggered()
{ //缩小显示
    pixRatio=pixRatio*0.8; //在当前比例基础上乘以0.8

    int w=pixRatio*curPixmap.width();// 显示宽度
    int h=pixRatio*curPixmap.height();//显示高度

    QPixmap pix=curPixmap.scaled(w,h); //图片缩放到指定高度和宽度,保持长宽比例

    ui->LabPicture->setPixmap(pix);
}

void MainWindow::on_actZoomIn_triggered()
{//放大显示
    pixRatio=pixRatio*1.2;//在当前比例基础上乘以0.8

    int w=pixRatio*curPixmap.width();// 显示宽度
    int h=pixRatio*curPixmap.height();//显示高度

    QPixmap pix=curPixmap.scaled(w,h);//图片缩放到指定高度和宽度,保持长宽比例
    ui->LabPicture->setPixmap(pix);
}

void MainWindow::on_actZoomFitW_triggered()
{ //适应宽度显示
    int w=ui->scrollArea->width()-20;//得到scrollArea的高度
    int realw=curPixmap.width();//原始图片的实际宽度
    pixRatio=float(w)/realw;//当前显示比例,必须转换为浮点数

    QPixmap pix=curPixmap.scaledToWidth(w-30);
    ui->LabPicture->setPixmap(pix);
}

void MainWindow::on_actZoomFitH_triggered()
{//适应高度显示图片
    int H=ui->scrollArea->height();//得到scrollArea的高度
    int realH=curPixmap.height(); //原始图片的实际高度
    pixRatio=float(H)/realH;  //当前显示比例,必须转换为浮点数

    QPixmap pix=curPixmap.scaledToHeight(H-30); //图片缩放到指定高度
    ui->LabPicture->setPixmap(pix);  //设置Label的PixMap
}

void MainWindow::on_actZoomRealSize_triggered()
{ //实际大小显示
    pixRatio=1;  //恢复显示比例为1
    ui->LabPicture->setPixmap(curPixmap);
}

void MainWindow::on_actDeleteItem_triggered()
{//删除节点
    QTreeWidgetItem* item =ui->treeFiles->currentItem(); //当前节点
    QTreeWidgetItem* parItem=item->parent(); //父节点
    parItem->removeChild(item);//The removed item will not be deleted
    delete item;
}

void MainWindow::on_actScanItems_triggered()
{//遍历节点
    for (int i=0;i<ui->treeFiles->topLevelItemCount();i++)
    {
        QTreeWidgetItem *item=ui->treeFiles->topLevelItem(i); //顶层节点
        changeItemCaption(item); //更改节点标题
    }
}

void MainWindow::on_actDockVisible_toggled(bool arg1)
{// 停靠区的可见性
    ui->dockWidget->setVisible(arg1);
}

void MainWindow::on_dockWidget_visibilityChanged(bool visible)
{//停靠区可见性变化
    ui->actDockVisible->setChecked(visible);
}

void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)
{//停靠区浮动性变化
    ui->actDockFloat->setChecked(topLevel);
}

void MainWindow::on_actDockFloat_triggered(bool checked)
{//停靠区浮动性
    ui->dockWidget->setFloating(checked);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/850198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享:2023新手做闲鱼电商如何轻松过万。详细步骤分享

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 如果一个人想赚很多钱&#xff0c;他必须学会从小钱开始。如果他想赚一点钱&#xff0c;他必…

springboot(2)

springmvc 把软件系统分为3个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器 &#xff08;Controller&#xff09;。 模型&#xff08;Model&#xff09;&#xff1a;Model是由一个实体Bean实现的&#xff0c;是数据的载体…

Modbus TCP转Profibus DP网关modbus tcp报文解析

捷米JM-DPM-TCP网关。在Profibus总线侧作为主站&#xff0c;在以太网侧作为ModbusTcp服务器功能&#xff0c; 下面是介绍捷米JM-DPM-TCP主站网关组态工具的配置方法 2, Profibus主站组态工具安装 执行资料光盘中的安装文件setup64.exe或setup.exe安装组态工具。安装过程中一直…

画原型只需6招,快速成原型图!

画原型图&#xff0c;是产品设计过程中的重头戏。一个优秀的原型图&#xff0c;能把设计理念以视觉的形式呈现出来&#xff0c;让团队感受产品的交互和体验&#xff0c;明确下一步要做什么。那么&#xff0c;怎样才能画出高质量的原型图呢&#xff1f;下面就来介绍几招实用的技…

文件传输软件的市场现状和未来趋势

文件传输软件是一种能够在不同计算机之间高效、便捷、安全地传送各种类型的文件的应用软件。它是计算机领域中的一项重要技术&#xff0c;涉及到网络通信、数据加密、文件管理等多个方面。随着互联网和移动互联网的发展&#xff0c;文件传输软件的市场需求也日益增大&#xff0…

每日汇评:在50日移动均线下方,黄金的下行势头依然强劲

1、黄金价格连续第二天下跌&#xff0c;美元在周五的抛售后恢复稳定&#xff1b; 2、在中国和美国公布关键通胀数据之前&#xff0c;投资者保持谨慎&#xff1b; 3、在日相对强弱指数(RSI)偏弱的情况下&#xff0c;金价在持续跌破1925美元的情况下&#xff0c;可能跌至1910美…

嵌入式开发学习(STC51-3-点亮led)

内容 点亮第一个led&#xff1b; led闪烁&#xff1b; led流水灯&#xff1b; led简介 led即发光二极管&#xff0c;它具有单向导电性&#xff0c;通过5mA左右电流即可发光&#xff0c;电流越大&#xff0c;其亮度越强&#xff0c;但若电流过大&#xff0c;会烧毁二极管&…

Matplotlib引领数据图表绘制

Matplotlib引领数据图表绘制 前言图像得组成画图设置 figure设置标题设置坐标轴设置 label 和 legend添加注释使用子图中文乱码解决保存图形显示图形条形图直方图散点图饼状图 总结 前言 在数据科学领域&#xff0c;数据可视化是一种强大的工具&#xff0c;能够将复杂的数据转…

Redis单机,主从,哨兵,集群四大模式

Redis 单机模式 Redis 单机模式是指 Redis 数据库在单个服务器上以独立的、单一的进程运行的模式。在这种模式下&#xff0c;Redis 不涉及数据分片或集群配置&#xff0c;所有的数据和操作都在一个实例中进行。以下是关于 Redis 单机模式的详细介绍&#xff1a; 单一实例&#…

数据连接,图文档与BOM数据紧密相连

在现代制造业的产品开发和生产过程中&#xff0c;图文档和BOM数据是不可或缺的重要信息。图文档记录了产品的设计和工程数据&#xff0c;而BOM数据明确了产品所需物料的清单和规格。然而&#xff0c;由于图文档和BOM数据分属不同的系统&#xff0c;数据之间的连接和共享往往成为…

赢在起跑线:美国计算机读研规划攻略

以下是一个去美国学计算机的读研规划&#xff0c;供您参考&#xff1a;01 基础准备 学术准备&#xff1a;在本科阶段&#xff0c;您需要确保已经掌握了计算机科学的基本知识和技能&#xff0c;包括计算机体系结构、编程语言、数据结构和算法等。同时&#xff0c;建议您参与一…

[学习笔记]微信小程序全套开发流程(ing)

https://www.bilibili.com/video/BV1mV4y1o7fu 1.整体概述 2.环境搭建 略 4.纯净版项目 5.快速入门 5.1组件(类似HTML标签) wxml中的标签html中的标签textspanviewdivimageimgiconnavigatora view组件 <view><view class"c0">学生&#xff1a;<…

怎样理解黑盒测试和白盒测试?二者有什么关系

按照使用的测试技术可以将软件测试分为黑盒测试与白盒测试。 &#xff08;1&#xff09;黑盒测试 黑盒测试就是把软件(程序)当作一个有输入与输出的黑匣子&#xff0c;它把程序当作一个输入域到输出域的映射&#xff0c;只要输入的数据能输出预期的结果即可&#xff0c;不必关…

吉利科技携手企企通,打造集团化数智供应链系统

近日&#xff0c;吉利科技集团有限公司&#xff08;以下简称“吉利科技”&#xff09;联合企企通成功召开SRM采购供应链管理项目启动会。企企通与吉利科技高层、项目负责人与团队成员出席此次启动会。 双方将携手在企业供应商全生命周期管理、采购全流程、电子招投标、采购分析…

打造本地户外装备小程序商城教程大揭秘

在如今的移动互联网时代&#xff0c;小程序已经成为了各行各业的发展利器。尤其对于户外用具行业来说&#xff0c;一个专属的小程序商城将能够极大地提升企业的品牌形象和销售业绩。下面就来介绍一下快速上手制作户外用具小程序的攻略吧。 首先&#xff0c;登录乔拓云平台进入商…

TDengine + Telegraf + Grafana 实现图形化服务器状态监控

TDengine Telegraf Grafana 实现图形化服务器状态监控 技术栈环境搭建安装tdenginue下载安装包解压文件运行安装文件启动td运行 taosAdapter 安装Telegraf添加yum源安装生成配置文件修改配置文件启动telegraf 安装Grafana直接yum安装安装td数据源配置启动Grafana配置数据源导…

2021年12月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 昨天的温度是5摄氏度,今天降温7摄氏度,今天的温度是多少摄氏度? A:12 B:7 C:2 D:-2 正确的答案是 D:-2。 解析: 根据题目描述,昨天的温度是 5 摄氏度,今天降温了 7 摄氏度。降温意味着温度变低,所以今天的温度…

嵌入式开发实用工具——QFSViewer

嵌入式开发实用工具——QFSViewer 介绍 今天给大家推荐个我个人业余时间开发的一个嵌入式开发实用工具——QFSViewer&#xff0c;这个工具主要是用来加载查看各种嵌入式常用的文件系统映像&#xff0c;目前支持JFSS2、Fat32、Fat16、Fat12、exFat、Ext2、Ext3、Ext4等文件系统…

性能测试之性能测试指标详解(详细)

前言 刚开始&#xff0c;以为做性能测试&#xff0c;就是做些脚本、参数化、关联&#xff0c;压起来之后&#xff0c;再扔出一个结果。 但实际上不止这些内容&#xff0c;还要加上性能分析&#xff0c;关注调优之后响应时间有多大的提升&#xff0c;TPS 有多大的提高&#xf…

区块链学习6-长安链部署:如何创建特定共识节点数和同步节点数的链

正常prepare的时候只支持4 7 13 16个节点个数&#xff0c;想要创建10个节点&#xff0c;其中5个是共识节点&#xff0c;如何实现&#xff1f; 1. 注释掉prepare.sh的这几行&#xff1a; 2. 修改 crytogen的模板文件&#xff1a; 如果是cert模式&#xff1a;chainmaker-crypt…