Qt第八天

QTreeWidget和QDockWidget用法

本例子以QTreeWidget为主要组件,创建一个照片管理器

头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>
#include<QLabel>
#include<QTreeWidget>
namespace Ui {
class MainWindow;
}


class MainWindow : public QMainWindow
{
    Q_OBJECT


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


private slots:
    void on_actAddFolder_triggered();


    void on_actAddFiles_triggered();


    void on_treeFiles_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);


    void on_actDeleteItem_triggered();


    void on_actScanItems_triggered();


    void on_actZoomFitH_triggered();


    void on_actZoomIn_triggered();


    void on_actZoomRealSize_triggered();


    void on_actZoomFitW_triggered();


    void on_actZoomOut_triggered();


    void on_actDockVisible_toggled(bool arg1);


    void on_actDockFloat_triggered(bool checked);


    void on_dockWidget_visibilityChanged(bool visible);


    void on_dockWidget_topLevelChanged(bool topLevel);


private:
    Ui::MainWindow *ui;
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); //遍历改变节点标题
};


#endif // MAINWINDOW_H


mainwindow.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    LabFileName=new QLabel("");
    ui->statusBar->addWidget(LabFileName);//状态栏添加标签
    this->setCentralWidget(ui->scrollArea);//将scrollArea设为中心窗口
    iniTree();//初始化目录树
}


MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::iniTree()//初始化目录树
{
    QString dataStr="";//Item的Data储存的String
    ui->treeFiles->clear();//清空TreeWidget中的内容
    QIcon icon;
    icon.addFile(":/images/icons/15.ico");//添加标签
    QTreeWidgetItem *item=new QTreeWidgetItem(MainWindow::itTopItem);//创建节点
    item->setIcon(MainWindow::colItem,icon);//第一列图标
    item->setText(MainWindow::colItem,"图片文件");//第一列文字
    item->setText(MainWindow::colItemType,"type=itTopItem");//第二列文字
    item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsAutoTristate|Qt::ItemIsEnabled);
                   //可选择的,可被复选,可被使能,允许Check的第三种状态
    item->setCheckState(colItem,Qt::Checked);//设置第一列处于被选择状态
    item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr));
    ui->treeFiles->addTopLevelItem(item);//添加顶层节点
}


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


    QTreeWidgetItem *item; //节点
    item=new QTreeWidgetItem(MainWindow::itGroupItem); //新建节点, 设定type为 itGroupItem
    item->setIcon(colItem,icon); //设置图标
    item->setText(colItem,NodeText); //最后的文件夹名称,第1列
    //item->setText(colSecond,"type=itGroupItem; data="+dirName); //完整目录名称
    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); //在父节点下面添加子节点
}


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


}


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::on_actAddFiles_triggered()//actAddFile槽函数
{
    QStringList files=QFileDialog::getOpenFileNames(this,"选择一个或多个文件","","Images(*.jpg)");//多选文件
    //首先使用getOpenFileNames获取图片文件的列表
    if (files.isEmpty()) //如果一个文件都没选
        return;


    QTreeWidgetItem *parItem,*item; //节点
    item=ui->treeFiles->currentItem(); //当前节点
                                       //item->type()获取返回节点的类型
    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()
        addImageItem(parItem,aFilename); //添加一个图片节点
    }
}


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(colSecond,"type=itImageItem; data="+aFilename); //完整目录名称
        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::on_treeFiles_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
//目录树上的当前节点变化时,会发射currentItemChanged()信号,为此信号创建槽函数,实现当前节点类型判断
//几个Action的使能控制,显示图片
{
    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); //调用displayImage()显示图片
          break;
    }
}


//删除节点
void MainWindow::on_actDeleteItem_triggered()//actDeleteItem的槽函数
{
    QTreeWidgetItem* item =ui->treeFiles->currentItem(); //当前节点
    QTreeWidgetItem* parItem=item->parent(); //父节点
    parItem->removeChild(item);//移除一个字节点,并不会删除
    delete item;//删除子节点
}


//遍历节点
void MainWindow::on_actScanItems_triggered()//actScanItems的槽函数
{
    for (int i=0;i<ui->treeFiles->topLevelItemCount();i++)//topLevelItemCount()获取顶层节点的个数
    {
        QTreeWidgetItem *item=ui->treeFiles->topLevelItem(i); //顶层节点
        changeItemCaption(item); //调用changeItemCaption()函数更改节点标题包括这个节点及其子节点
    }
}


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));  //自己调用自己,可重入的函数
}


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


//适应高度
void MainWindow::on_actZoomFitH_triggered()//actZoomFitH的槽函数
{
    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_actZoomFitW_triggered()//actZoomFitW槽函数
{
    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);//设置Label的PixMap
}


//放大
void MainWindow::on_actZoomIn_triggered()//actZoomIn的槽函数
{
    pixRatio=pixRatio*1.2;//在当前比例基础上乘以1.2


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


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


//原始大小
void MainWindow::on_actZoomRealSize_triggered()//actZoomRealSize的槽函数
{
    pixRatio=1;  //恢复显示比例为1
    ui->LabPicture->setPixmap(curPixmap);
}


//缩小
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_actDockVisible_toggled(bool arg1)
{
    ui->dockWidget->setVisible(arg1);
}


//窗体浮动
void MainWindow::on_actDockFloat_triggered(bool checked)
{
    ui->dockWidget->setFloating(checked);
}


//停靠区可见性变化
void MainWindow::on_dockWidget_visibilityChanged(bool visible)//单击DockWidget上的关闭按钮时
                                                              //发射visibilityChanged(bool)信号
{
    ui->actDockVisible->setChecked(visible);
}


//停靠区浮动性变化
void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)//当拖动DockWidget组件时使其浮动或停靠时
                                                             //会发射topLevelChanged(bool)信号
{
    ui->actDockFloat->setChecked(topLevel);
}


mainwindow

在这里插入图片描述

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/theRookie1/article/details/84783852