0


Qt案例:实现显示图片

效果图:
image-20220808114316600

17.1 组件使用

17.1.1 QDockWidget

含义:停靠区窗口,和状态栏、标题栏是一个等级

属性:

  • allowedAreas:设置允许停靠区域,或者使用代码setAllowedAreas(Qt::DockWidgetAreas areas)
  • features:设置停靠的属性。setFeatures(DockWidgetFeatures features)
    image-20220807204704232

    17.1.2 QTreeWidget

含义:目录树

属性:

  • Columns页用于设计目录树的列,目录树可以有多个列。在设计器里可以添加、删除、移动列,设置列的文字、字体、前景色、背景色、文字对齐方式、图标等。
  • Items页面用于设计目录树的节点,可对每个节点设置属性,如文字、字体、图标等,特别是fags属性,可以设置节点是否可选、是否可编辑、是否有CheckBox等,还可以设置节点的CheckState。
    image-20220808114124488

    17.2 Action

image-20220807204906049

17.3 定义基本变量

  1. private:
  2. // 创建节点时用作type参数,自定义类型必须大于1000
  3. enum treeItemType{
  4. itTopItem = 1001,
  5. itGroupItem,
  6. itImageItem
  7. };
  8. enum treeColNum{
  9. colItem=0,
  10. colItemType=1
  11. };
  12. QLabel *LabFileName;// 显示状态栏文件名称
  13. QPixmap curPixmap; // 当前图片
  14. float pixRatio; // 当前图片比例
  15. // 初始化目录树
  16. void initTree();
  17. void addFolderItem(QTreeWidgetItem *parItem,QString dirName); // 添加目录
  18. QString getFinalFolderName(const QString &fullPathName); // 提取目录名称
  19. void addImageItem(QTreeWidgetItem *parItem,QString aFilename); // 添加图片
  20. void displayImage(QTreeWidgetItem *item); // 显示一个图片节点的图片
  21. void changeItemCaption(QTreeWidgetItem *item); // 遍历改变节点标题

17.4 目录树初始化

添加顶层节点

  1. MainWindow::MainWindow(QWidget *parent) :
  2. QMainWindow(parent),
  3. ui(new Ui::MainWindow)
  4. {
  5. ui->setupUi(this);
  6. // 状态栏显示文件名
  7. LabFileName = new QLabel("");
  8. ui->statusBar->addWidget(LabFileName);
  9. // 设置中心窗体
  10. this->setCentralWidget(ui->scrollArea);
  11. // 初始化目录树
  12. initTree();
  13. }
  14. void MainWindow::initTree()
  15. {
  16. QString dataStr = "";
  17. ui->treeWidget->clear(); // 清空目录树
  18. QIcon icon;
  19. icon.addFile(":/icons/icons/15.ico");
  20. QTreeWidgetItem *item = new QTreeWidgetItem(MainWindow::itTopItem); //?
  21. item->setIcon(MainWindow::colItem,icon); // 第一列图标
  22. item->setText(MainWindow::colItem,"图片文件"); // 第一列文字
  23. item->setText(MainWindow::colItemType,"type=itTopItem"); // 第二列文字
  24. item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
  25. item->setCheckState(colItem,Qt::Checked); // 第一列勾选
  26. item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr)); //?
  27. ui->treeWidget->addTopLevelItem(item);// 添加顶层节点
  28. }
  • QTreeWidget的每个节点都是一个QTree WidgetItem对象,添加一个节点前需先创建它,并做好相关设置。
  • setData()函数为节点的某一列设置一个角色数据,setData()函数原型为:void() TreeWidgetItem::setData(int column,int role,const QVariant &value)

  1. item->setData(MainWindow:colItem,Qt::UserRole,QVariant (datastr));

它为节点的第1列,角色Qt:UserRole,设置了一个字符串数据dataStr.Qt:UserRole是枚举类型Qt:ItemDataRole中一个预定义的值。

17.5 添加目录节点

定义3个函数

  1. // 获取文件名称
  2. QString MainWindow::getFinalFolderName(const QString &fullPathName)
  3. {
  4. return fullPathName.right(fullPathName.length()-fullPathName.lastIndexOf("/")-1);
  5. }
  1. // 添加节点函数
  2. void MainWindow::addFolderItem(QTreeWidgetItem *parItem, QString dirName)
  3. {
  4. QIcon icon(":/icons/icons/open3.bmp");
  5. QString NodeText = getFinalFolderName(dirName);
  6. QTreeWidgetItem *item = new QTreeWidgetItem(MainWindow::itGroupItem); // 传入目录的节点类型type值1001
  7. item->setIcon(colItem,icon);
  8. item->setText(colItem,NodeText);
  9. item->setText(colItemType,"type:itGroupItem");
  10. item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
  11. item->setCheckState(colItem,Qt::Checked);
  12. item->setData(colItem,Qt::UserRole,QVariant(dirName));
  13. parItem->addChild(item); // 在父节点添加子节点
  14. }
  1. // action关联函数
  2. void MainWindow::on_actAddFolder_triggered()
  3. {
  4. QString fullname = QFileDialog::getExistingDirectory();
  5. if(!fullname.isEmpty()){
  6. QTreeWidgetItem *parItem = ui->treeWidget->currentItem();
  7. if(parItem){
  8. addFolderItem(parItem,fullname);
  9. }else {
  10. // 创建弹窗
  11. QMessageBox::critical(this, tr("危险弹窗"), tr("请选择目标节点"),QMessageBox::Save | QMessageBox::Discard, QMessageBox::Discard);
  12. }
  13. }
  14. else {
  15. return;
  16. }
  17. }

17.6 添加图片节点

QFileDialog::getOpenFileNames函数可以实现添加多个文件

实现:

  1. 创建临时变量parItem和item;
  2. parItem用于最终的添加目标,item存放当前节点;
  3. 如果当前节点是文件节点或者顶层节点,则目标节点是当前节点;
  4. 如果当前节点是图片节点,则目标节点是图片节点的父节点(图片节点为末尾节点,后面不能添加子节点);
  5. 使用for循环分别获取文件的名称,并添加到目标节点下;
  1. void MainWindow::addImageItem(QTreeWidgetItem *parItem, QString aFilename)
  2. {
  3. QIcon icon(":/icons/icons/31.ico");
  4. QString NodeText = getFinalFolderName(aFilename);
  5. QTreeWidgetItem *item;
  6. item = new QTreeWidgetItem(MainWindow::itImageItem);
  7. item->setIcon(colItem,icon);
  8. item->setText(colItem,NodeText);
  9. item->setText(colItemType,"type=itImageItem");
  10. item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
  11. item->setData(colItem,Qt::UserRole,QVariant(aFilename));
  12. parItem->addChild(item); // 在父节点添加子节点
  13. }
  1. void MainWindow::on_actAddFiles_triggered()
  2. {
  3. QStringList files = QFileDialog::getOpenFileNames(this,"选择一个或者多个文件","","Images(*.jpg)");
  4. if(files.isEmpty())
  5. return;
  6. QTreeWidgetItem *parItem,*item;
  7. item = ui->treeWidget->currentItem();
  8. if(item){
  9. if(item->type()==itImageItem) // 当前节点是图片节点
  10. parItem = item->parent();
  11. else {
  12. parItem=item;
  13. }
  14. for (int i = 0;i<files.size();++i) {
  15. QString aFilename = files.at(i);
  16. addImageItem(parItem,aFilename);
  17. }
  18. }else {
  19. QMessageBox::critical(this, tr("危险弹窗"), tr("请选择目标节点"),QMessageBox::Save | QMessageBox::Discard, QMessageBox::Discard);
  20. }
  21. }

17.7 当前节点发生变化响应

QTreeWidget会发出currentItemChanged信号

实现:

  1. 获取当前节点的类型;
  2. 判断当前选中的节点属于哪个类型;
  3. 根据类型设置添加、删除等按钮的状态;
  4. 如果为图片节点,调用图片显示函数;

代码实现:

  1. void MainWindow::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
  2. {
  3. Q_UNUSED(previous);
  4. if(current==NULL)
  5. return;
  6. int var = current->type();
  7. switch (var) {
  8. case itTopItem:
  9. ui->actAddFolder->setEnabled(true);
  10. ui->actAddFiles->setEnabled(true);
  11. ui->actDeleteItem->setEnabled(false);
  12. break;
  13. case itGroupItem:
  14. ui->actAddFolder->setEnabled(true);
  15. ui->actAddFiles->setEnabled(true);
  16. ui->actDeleteItem->setEnabled(true);
  17. break;
  18. case itImageItem: // 当前选中为图片,不能添加子节点,显示图片
  19. ui->actAddFolder->setEnabled(false);
  20. ui->actAddFiles->setEnabled(true);
  21. ui->actDeleteItem->setEnabled(true);
  22. ui->actZoomFitH->setEnabled(true);
  23. ui->actZoomFitW->setEnabled(true);
  24. ui->actZoomIn->setEnabled(true);
  25. ui->actZoomOut->setEnabled(true);
  26. ui->actZoomRealSize->setEnabled(true);
  27. displayImage(current);
  28. break;
  29. }
  30. }

17.8 删除节点

删除节点使用QTreeWidgetItem对象上的removeChild函数

实现:

  1. 获取当前节点;
  2. 获取当前节点的父节点;
  3. 从父节点中删除子节点;

代码实现:

  1. void MainWindow::on_actDeleteItem_triggered()
  2. {
  3. QTreeWidgetItem *item = ui->treeWidget->currentItem();
  4. QTreeWidgetItem *parItem = item->parent();
  5. parItem->removeChild(item);
  6. delete item; // 删除子节点的内存空间。removveChild只能从父节点中删除子节点,但不能移除子节点的内存空间。
  7. }

17.9 遍历节点

使用递归调用

int topLevelItemCount():返回顶层节点个数。
QTree WidgetItemtopLevelItem(int index):返回序号为index的顶层节点。

int topLevelItemCount():返回顶层节点个数。
QTree WidgetItem*topLevelItem(int index):返回序号为index的顶层节点。

实现:

  1. 获取全部的顶层节点,遍历更改;
  2. 更改每个节点后,获取全部子节点并更改;

代码实现:

  1. void MainWindow::on_actScanItems_triggered()
  2. {
  3. int cnt = ui->treeWidget->topLevelItemCount();
  4. for(int i = 0;i<cnt;++i){
  5. QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i); // 顶层节点
  6. changeItemCaption(item); // 调用【更改节点标题】函数
  7. }
  8. }
  1. void MainWindow::changeItemCaption(QTreeWidgetItem *item)
  2. {
  3. // 节点标题前加*
  4. QString str = "*" + item->text(colItem);
  5. item->setText(colItem,str);
  6. if(item->childCount()>0){
  7. for (int i = 0;i<item->childCount();i++) {
  8. changeItemCaption(item->child(i));
  9. }
  10. }
  11. }

17.10 显示节点的图片

curPixmap是在MainWindow中定义的一个QPixmap类型的变量,用于操作图片。QPixmap:load(QString&cfileName)直接将一个图片文件载入。

实现:

  1. 获取存入的文件名称并在状态栏显示名称;
  2. 调用QPixmap下的load函数载入图片;
  3. 自适应高度显示图片;

这里还显示不了,还未写自适应高度显示action;

  1. void MainWindow::displayImage(QTreeWidgetItem *item)
  2. {
  3. QString filename = item->data(colItem,Qt::UserRole).toString(); // 获取文件名,之前用setData存的数据
  4. LabFileName->setText(filename); // 状态栏显示图片名称
  5. curPixmap.load(filename); // 当前图片
  6. on_actZoomFitH_triggered(); // 自适应高度显示
  7. }

17.11 图片显示与缩放

QPixmap存储图片数据,可以缩放图片,有以下几个函数。

  • QPixmap scaledToHeight(int height):返回一个缩放后的图片的副本,图片缩放到一个高度height.
  • QPixmap scaledTo Width(int width):返回一个缩放后的图片的副本,图片缩放到一个宽度width.
  • QPixmap scaled(int width,.int height):返回一个缩放后的图片的副本,图片缩放到宽度width和高度height,缺省为不保持比例。

变量curPixmap保存了图片的原始副本,要缩放只需调用curPixmap的相应函数,返回缩放后的图片副本。在界面上的一个标签LabPicture上显示图片,使用了QLabel的setPixmap(const QPixmap&)函数。

  1. void MainWindow::on_actZoomFitH_triggered()
  2. {
  3. // 自适应高度显示
  4. int H = ui->scrollArea->height(); // 获取当前滑动块的高度
  5. int realH = curPixmap.height(); // 获取当前图片的高度
  6. pixRatio = float(H)/realH; // 当前图片显示的比例(必须是浮点数)
  7. QPixmap pix = curPixmap.scaledToHeight(H-30); // 图片缩放指定高度
  8. ui->label->setPixmap(pix); // label标签显示图片
  9. }
  10. void MainWindow::on_actZoomFitW_triggered()
  11. {
  12. // 自适应宽度显示
  13. int W = ui->scrollArea->width(); // 获取当前滑动块的高度
  14. int realW = curPixmap.width(); // 获取当前图片的高度
  15. pixRatio = float(W)/realW; // 当前图片显示的比例(必须是浮点数)
  16. QPixmap pix = curPixmap.scaledToWidth(W-30); // 图片缩放指定高度
  17. ui->label->setPixmap(pix); // label标签显示图片
  18. }
  19. void MainWindow::on_actZoomIn_triggered()
  20. {
  21. // 放大显示
  22. pixRatio = pixRatio*1.2;
  23. int w = pixRatio*curPixmap.width();
  24. int h = pixRatio*curPixmap.height();
  25. QPixmap pix = curPixmap.scaled(w,h);
  26. ui->label->setPixmap(pix);
  27. }
  28. void MainWindow::on_actZoomOut_triggered()
  29. {
  30. // 缩小显示
  31. pixRatio = pixRatio*0.8;
  32. int w = pixRatio*curPixmap.width();
  33. int h = pixRatio*curPixmap.height();
  34. QPixmap pix = curPixmap.scaled(w,h);
  35. ui->label->setPixmap(pix);
  36. }
  37. void MainWindow::on_actZoomRealSize_triggered()
  38. {
  39. // 实际大小
  40. pixRatio = 1;
  41. ui->label->setPixmap(curPixmap);
  42. }

17.12 dockWidget

只写action按钮的动作,手动拖动dockWidget时按钮的状态不会改变,需要使用dockWidget上的信号;

隐藏发射信号visibilityChanged(bool)
浮动、停靠信号topLevelChanged(bool)

  1. void MainWindow::on_actDockVisible_toggled(bool arg1)
  2. {
  3. ui->dockWidget->setVisible(arg1);
  4. }
  5. void MainWindow::on_actDockFloat_toggled(bool arg1)
  6. {
  7. ui->dockWidget->setFloating(arg1);
  8. }
  9. void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)
  10. {
  11. ui->actDockFloat->setChecked(topLevel);
  12. }
  13. void MainWindow::on_dockWidget_visibilityChanged(bool visible)
  14. {
  15. ui->actDockVisible->setChecked(visible);
  16. }
标签: qt ui c++

本文转载自: https://blog.csdn.net/weixin_57064740/article/details/126224617
版权归原作者 摩天仑 所有, 如有侵权,请联系我们删除。

“Qt案例:实现显示图片”的评论:

还没有评论