C/C++ QT图形开发高级组件

QT 是一个跨平台,并使用C++作为开发语言的应用程序开发工具,其提供了一套类库,该类库实现全平台支持,前面的内容主要学习了基础组建的使用,下面则是高级组件的使用,QT中的高级组件我把它分为,QListWidget,QTreeWidget,QTableWidget,QGroupBox,MDIArea,DockWidget等,这些组件更加的灵活,下面给则是我总结的学习笔记,供大家参考。

分页组件与计算器:

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

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

    // ----------------------------------------------------------------------------------
    // 全局配置tabWidget选项卡
    ui->tabWidget->setTabPosition(QTabWidget::North);       // 设置选项卡方位
    ui->tabWidget->setIconSize(QSize(50, 25));              // 设置图标整体大小
    ui->tabWidget->setTabShape(QTabWidget::Triangular);     // 设置选项卡形状
    ui->tabWidget->setMovable(true);                        // 设置选项卡是否可拖动
    ui->tabWidget->usesScrollButtons();                     // 选项卡滚动

    // 设置选项卡1
    ui->tabWidget->setTabText(0,QString("SpinBox"));             // 设置选项卡文本
    ui->tabWidget->setTabIcon(0,QIcon(":/image/1.ico"));         // 设置选项卡图标
    ui->tabWidget->setTabToolTip(0,QString("SpinBox与进制转换"));  // 设置鼠标悬停提示

    // 设置选项卡2
    ui->tabWidget->setTabText(1,QString("QSlide"));              // 设置选项卡文本
    ui->tabWidget->setTabIcon(1,QIcon(":/image/2.ico"));         // 设置选项卡图标
    ui->tabWidget->setTabToolTip(1,QString("滑块条的使用"));       // 设置鼠标悬停提示

    // 设置选项卡3
    ui->tabWidget->setTabText(2,QString("QSlide"));              // 设置选项卡文本
    ui->tabWidget->setTabIcon(2,QIcon(":/image/3.ico"));         // 设置选项卡图标
    ui->tabWidget->setTabToolTip(2,QString("滑块条的使用"));       // 设置鼠标悬停提示

    // ----------------------------------------------------------------------------------
    // 将选项卡1中,数量和单价两个SpinBox的valueChanged()信号与on_pushButton_clicked()槽关联
    // 只要spinBox中的内容发生变化,则立即触发按钮完成计算
    QObject::connect(ui->spinBox,SIGNAL(valueChanged(int)),this,SLOT(on_pushButton_clicked()));
    QObject::connect(ui->doubleSpinBox,SIGNAL(valueChanged(double)),this,SLOT(on_pushButton_clicked()));
}

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

// 实现点击计算按钮后的计算
void MainWindow::on_pushButton_clicked()
{
    int number = ui->spinBox->value();               // 获取数量
    float price = ui->doubleSpinBox->value();        // 获取单价
    float total = number * price;                    // 计算
    ui->doubleSpinBox_2->setValue(total);            // 得到结果
}

多选框:

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

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

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

// 初始化列表 listWidget
void MainWindow::on_pushButton_clicked()
{
    // 每一行是一个QListWidgetItem
    QListWidgetItem *aItem;

    // 设置ICON的图标
    QIcon aIcon;
    aIcon.addFile(":/image/1.ico");

    ui->listWidget->clear();
    for(int x=0;x<10;x++)
    {
        QString str = QString::asprintf("192.168.1.%d",x);
        aItem = new QListWidgetItem();   // 新建一个项

        aItem->setText(str);                   // 设置文字标签
        aItem->setIcon(aIcon);                 // 设置图标
        aItem->setCheckState(Qt::Checked);     // 设为选中状态
        aItem->setFlags(Qt::ItemIsSelectable |  // 设置为不可编辑状态
                         Qt::ItemIsUserCheckable
                        |Qt::ItemIsEnabled);

        ui->listWidget->addItem(aItem); //增加项
    }
}

// 设置所有项设置为可编辑状态
void MainWindow::on_pushButton_5_clicked()
{
    int x,cnt;
    QListWidgetItem *aItem;

    cnt = ui->listWidget->count();
    for(x=0;x<cnt;x++)
    {
        aItem = ui->listWidget->item(x);
        aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
                        |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
    }
}

// 全选按钮
void MainWindow::on_pushButton_2_clicked()
{
    int cnt = ui->listWidget->count();   // 获取总数
    for(int x=0;x<cnt;x++)
    {
        QListWidgetItem *aItem = ui->listWidget->item(x);  // 获取到一项指针
        aItem->setCheckState(Qt::Checked);                 // 设置为选中
    }

}

// 全不选
void MainWindow::on_pushButton_3_clicked()
{
    int cnt = ui->listWidget->count();   // 获取总数
    for(int x=0;x<cnt;x++)
    {
        QListWidgetItem *aItem = ui->listWidget->item(x);  // 获取到一项指针
        aItem->setCheckState(Qt::Unchecked);               // 设置为非选中
    }
}

// 反选
void MainWindow::on_pushButton_4_clicked()
{
    int x,cnt;
    QListWidgetItem *aItem;

    cnt = ui->listWidget->count();
    for(x=0;x<cnt;x++)
    {
        aItem = ui->listWidget->item(x);
        if(aItem->checkState() != Qt::Checked)
            aItem->setCheckState(Qt::Checked);
        else
            aItem->setCheckState(Qt::Unchecked);
    }
}

// 删除选中项
void MainWindow::on_pushButton_6_clicked()
{
    int row = ui->listWidget->currentRow(); // 获取当前行
    QListWidgetItem *aItem = ui->listWidget->takeItem(row);  // 移除指定行的项,但不delete
    delete aItem;                                            // 释放空间
}

// 增加一项,尾部追加
void MainWindow::on_pushButton_7_clicked()
{
    QIcon aIcon;
    aIcon.addFile(":/image/2.ico");

    QListWidgetItem *aItem = new QListWidgetItem("新增的项目");   // 增加项目名
    aItem->setIcon(aIcon);                                       // 设置图标
    aItem->setCheckState(Qt::Checked);                           // 设置为选中
    aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
    ui->listWidget->addItem(aItem);                              // 增加到控件
}

// 指定位置插入一项
void MainWindow::on_pushButton_8_clicked()
{
    QIcon aIcon;
    aIcon.addFile(":/image/3.ico");

    QListWidgetItem *aItem = new QListWidgetItem("插入的数据");
    aItem->setIcon(aIcon);
    aItem->setCheckState(Qt::Checked);
    aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);

    // 在当前行的上方插入一个项
    ui->listWidget->insertItem(ui->listWidget->currentRow(),aItem);
}

// listWidget当前选中项发生变化
void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    QString str;
    if (current != NULL) //需要检测变量指针是否为空
    {
      if (previous==NULL)  //需要检测变量指针是否为空
        str="当前:"+current->text();
      else
        str="前一项:" + previous->text() + "; 当前项:" + current->text();
      std::cout << str.toStdString().data() << std::endl;
    }
}

// 当右键被点击时弹出菜单
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{

}


为多选框增加右键菜单:

#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <iostream>

// 全局下设置增加删除菜单
QAction *NewAction;
QAction *InsertAction;
QAction *DeleteAction;

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

    // 使用 customContextMenuRequested 信号则需要设置
    ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);

    // 隐藏菜单栏上的右击菜单
    this->setContextMenuPolicy(Qt::NoContextMenu);

    // 创建基础顶部菜单
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);
    QMenu * fileMenu = bar->addMenu("菜单1");

    // 添加子菜单
     NewAction = fileMenu->addAction("增加IP地址");
     InsertAction = fileMenu->addAction("插入IP地址");
     DeleteAction = fileMenu->addAction("删除IP地址");

    // 分别设置图标
    NewAction->setIcon(QIcon(":/image/1.ico"));
    InsertAction->setIcon(QIcon(":/image/2.ico"));
    DeleteAction->setIcon(QIcon(":/image/3.ico"));

    // 绑定槽函数
    connect(NewAction,&QAction::triggered,this,[=](){
        std::cout << "new action" << std::endl;
    });

    connect(InsertAction,&QAction::triggered,this,[=](){
        std::cout << "insert action" << std::endl;
    });

    // 以删除为例,演示如何删除选中行
    connect(DeleteAction,&QAction::triggered,this,[=](){
        int row = ui->listWidget->currentRow();
        QListWidgetItem *aItem = ui->listWidget->takeItem(row);
        delete aItem;
        std::cout << "delete action" << std::endl;
    });
}

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

// 当listWidget被右键点击时则触发
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
    std::cout << "x pos = "<< pos.x() << "y pos = " << pos.y() << std::endl;
    Q_UNUSED(pos);

    // 新建Menu菜单
    QMenu *ptr = new QMenu(this);

    // 添加Actions创建菜单项
    ptr->addAction(NewAction);
    ptr->addAction(InsertAction);
    // 添加一个分割线
    ptr->addSeparator();
    ptr->addAction(DeleteAction);

    // 在鼠标光标位置显示右键快捷菜单
    ptr->exec(QCursor::pos());

    // 手工创建的指针必须手工删除
    delete ptr;
}


多选框的图标模式:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <iostream>

// 全局下设置增加删除菜单
QAction *NewAction;
QAction *InsertAction;
QAction *DeleteAction;

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

    // 使用 customContextMenuRequested 信号则需要设置
    ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);

    // 隐藏菜单栏上的右击菜单
    this->setContextMenuPolicy(Qt::NoContextMenu);

    // 创建基础顶部菜单
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);
    QMenu * fileMenu = bar->addMenu("菜单1");
    bar->setVisible(false);   // 隐藏顶部菜单栏

    // 添加子菜单
     NewAction = fileMenu->addAction("增加IP地址");
     InsertAction = fileMenu->addAction("插入IP地址");
     DeleteAction = fileMenu->addAction("删除IP地址");

    // 分别设置图标
    NewAction->setIcon(QIcon(":/image/1.ico"));
    InsertAction->setIcon(QIcon(":/image/2.ico"));
    DeleteAction->setIcon(QIcon(":/image/3.ico"));

    // 绑定槽函数
    connect(NewAction,&QAction::triggered,this,[=](){
        std::cout << "new action" << std::endl;
    });

    connect(InsertAction,&QAction::triggered,this,[=](){
        std::cout << "insert action" << std::endl;
    });

    // 以删除为例,演示如何删除选中行
    connect(DeleteAction,&QAction::triggered,this,[=](){
        int row = ui->listWidget->currentRow();
        QListWidgetItem *aItem = ui->listWidget->takeItem(row);
        delete aItem;
        std::cout << "delete action" << std::endl;
    });


    // 第二个ListWidget_使用图标方式展示
    ui->listWidget_2->setViewMode(QListView::IconMode);

    // 每一行是一个QListWidgetItem
    QListWidgetItem *aItem;

    // 设置ICON的图标
    QIcon aIcon;
    aIcon.addFile(":/image/1.ico");

    ui->listWidget_2->clear();
    for(int x=0;x<10;x++)
    {
        QString str = QString::asprintf("admin_%d",x);
        aItem = new QListWidgetItem();   // 新建一个项

        aItem->setText(str);                   // 设置文字标签
        aItem->setIcon(aIcon);                 // 设置图标
        //aItem->setCheckState(Qt::Checked);     // 设为选中状态
        aItem->setFlags(Qt::ItemIsSelectable |  // 设置为不可编辑状态
                         Qt::ItemIsUserCheckable
                        |Qt::ItemIsEnabled);

        ui->listWidget_2->addItem(aItem); //增加项
    }
}

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

// 当listWidget被右键点击时则触发
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
    std::cout << "x pos = "<< pos.x() << "y pos = " << pos.y() << std::endl;
    Q_UNUSED(pos);

    // 新建Menu菜单
    QMenu *ptr = new QMenu(this);

    // 添加Actions创建菜单项
    ptr->addAction(NewAction);
    ptr->addAction(InsertAction);
    // 添加一个分割线
    ptr->addSeparator();
    ptr->addAction(DeleteAction);

    // 在鼠标光标位置显示右键快捷菜单
    ptr->exec(QCursor::pos());

    // 手工创建的指针必须手工删除
    delete ptr;
}


treeWidget 实现的输出,与右键菜单实现

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QIcon>
#include <QString>

// 全局下设置增加删除菜单
QAction *NewAction;
QAction *InsertAction;
QAction *DeleteAction;

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

    ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);


    // 创建基础顶部菜单
   QMenuBar *bar = menuBar();
   this->setMenuBar(bar);
   QMenu * fileMenu = bar->addMenu("菜单1");

   // 添加子菜单
    NewAction = fileMenu->addAction("获取行号");
    InsertAction = fileMenu->addAction("获取本行数据");
    DeleteAction = fileMenu->addAction("删除IP地址");

    // 分别设置图标
    NewAction->setIcon(QIcon(":/image/1.ico"));
    InsertAction->setIcon(QIcon(":/image/2.ico"));
    DeleteAction->setIcon(QIcon(":/image/3.ico"));

    // 绑定槽函数
    connect(NewAction,&QAction::triggered,this,[=](){
        std::cout << "new action" << std::endl;
        int row = ui->treeWidget->currentColumn();
        std::cout << row << std::endl;
    });

    connect(InsertAction,&QAction::triggered,this,[=](){
        std::cout << "insert action" << std::endl;
        QString msg = ui->treeWidget->currentItem()->text(0);
        std::cout << msg.toStdString().data() << std::endl;
    });

    // 获得行号
    connect(DeleteAction,&QAction::triggered,this,[=](){
        std::cout << "delete action" << std::endl;
        int row  = ui->treeWidget->currentIndex().row();
        std::cout << row << std::endl;
    });

    ui->treeWidget->setColumnCount(4);
    ui->treeWidget->setColumnWidth(0,200);

    QTreeWidgetItem* item=new QTreeWidgetItem();
    item->setText(0,"<Frist Lyshark>");
    item->setIcon(0,QIcon(":/image/3.ico"));
    item->setText(1,"2020-12-11");
    item->setText(2,"*.pdf");
    item->setText(3,"102MB");
    ui->treeWidget->addTopLevelItem(item);

    QTreeWidgetItem* item1=new QTreeWidgetItem();
    item1->setText(0,"<Frist wang>");
    item1->setIcon(0,QIcon(":/image/3.ico"));
    item1->setText(1,"2010-11-11");
    item1->setText(2,"*.pdf");
    item1->setText(3,"12MB");
    ui->treeWidget->addTopLevelItem(item1);

    QStringList headers;

    headers.append("文件名");
    headers.append("更新时间");
    headers.append("文件类型");
    headers.append("文件大小");
    ui->treeWidget->setHeaderLabels(headers);
}

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

void MainWindow::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
    std::cout << "x pos = "<< pos.x() << "y pos = " << pos.y() << std::endl;
    Q_UNUSED(pos);

      // 新建Menu菜单
      QMenu *ptr = new QMenu(this);

      // 添加Actions创建菜单项
      ptr->addAction(NewAction);
      ptr->addAction(InsertAction);
      // 添加一个分割线
      ptr->addSeparator();
      ptr->addAction(DeleteAction);

      // 在鼠标光标位置显示右键快捷菜单
      ptr->exec(QCursor::pos());

      // 手工创建的指针必须手工删除
      delete ptr;
}

tree的多节点并驾齐驱

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

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

    // 设置QTreeWidget的列数
    ui->treeWidget->setColumnCount(1);
    // 设置QTreeWidget标题隐藏
    ui->treeWidget->setHeaderHidden(true);

    // 创建QTreeWidget的朋友节点,父节点是tree
    QTreeWidgetItem *Friend = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("朋友")));
    Friend->setIcon(0,QIcon(":/image/4.ico"));  // 添加一个图标
    Friend->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                     | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    Friend->setCheckState(0,Qt::Checked);       // 设置为选中

    // 给Friend添加一个子节点frd
    QTreeWidgetItem *frd = new QTreeWidgetItem(Friend);
    frd->setText(0,"老张");
    frd->setIcon(0,QIcon(tr(":/image/1.ico")));

    QTreeWidgetItem *frs = new QTreeWidgetItem(Friend);
    frs->setText(0,"老王");
    frs->setIcon(0,QIcon(tr(":/image/1.ico")));

    // ----------------------------------------------------------
    // 创建名叫同学节点,父节点同样是tree
    QTreeWidgetItem * ClassMate = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("同学")));
    ClassMate->setIcon(0,QIcon(":/image/5.ico"));  // 添加一个图标

    //Fly是ClassMate的子节点
    QTreeWidgetItem *Fly = new QTreeWidgetItem(QStringList(QString("张三")));
    Fly->setIcon(0,QIcon(tr(":/image/2.ico")));
    //创建子节点的另一种方法
    ClassMate->addChild(Fly);

    QTreeWidgetItem *Fls = new QTreeWidgetItem(QStringList(QString("李四")));
    Fls->setIcon(0,QIcon(tr(":/image/2.ico")));
    ClassMate->addChild(Fls);

    // ----------------------------------------------------------
    // 陌生人单独一栏
    QTreeWidgetItem  *Strange = new QTreeWidgetItem(true);
    Strange->setText(0,"陌生人");
    Strange->setIcon(0,QIcon(":/image/6.ico"));  // 添加一个图标

    ui->treeWidget->addTopLevelItem(ClassMate);
    ui->treeWidget->addTopLevelItem(Strange);

    //展开QTreeWidget的所有节点
    //ui->treeWidget->expandAll();
    //ui->treeWidget->resize(271,401);
}

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

QTreeWidgetItem * MainWindow::AddTreeRoot(QString name,QString desc)
{
    QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
    ui->treeWidget->addTopLevelItem(item);
    return item;
}

QTreeWidgetItem * MainWindow::AddTreeNode(QTreeWidgetItem *parent,QString name,QString desc)
{
    QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
    parent->addChild(item);
    return item;
}

// 当我们双击指定的成员时获取到该成员的名字
void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->text(column);
    std::cout << str.toStdString().data() << std::endl;
}

// 当我们单击指定成员时获取数据
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->text(column);
    std::cout << str.toStdString().data() << std::endl;
}

// 单击按钮添加新的父节点
void MainWindow::on_pushButton_clicked()
{
    QString NodeText = "新的父节点";
    QTreeWidgetItem  *item = new QTreeWidgetItem(true);
    item->setText(0,NodeText);
    item->setIcon(0,QIcon(":/image/7.ico"));
    ui->treeWidget->addTopLevelItem(item);
}

// 单击按钮添加子节点
void MainWindow::on_pushButton_4_clicked()
{
    QTreeWidgetItem * item= ui->treeWidget->currentItem();
        if(item!=NULL)
            AddTreeNode(item,"新子节点","新子节点");
        else
            AddTreeRoot("新子节点","新子节点");
}

// 单击后将指定节点修改为Modify并将图标设置为新的
void MainWindow::on_pushButton_2_clicked()
{
    // 得到当前节点
    QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
        return;
    // 修改选中项
    for(int x=0;x<currentItem->columnCount();x++)
    {
        currentItem->setText(x,tr("Modify") + QString::number(x));
        currentItem->setIcon(x,QIcon(":/image/1.ico"));
    }

}

// 删除选中的节点
void MainWindow::on_pushButton_3_clicked()
{
    QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
        return;

    // 如果没有父节点则直接删除
    if(currentItem->parent() == NULL)
    {
        delete ui->treeWidget->takeTopLevelItem(ui->treeWidget->currentIndex().row());
        std::cout << ui->treeWidget->currentIndex().row() << std::endl;
    }
    else
    {
        // 如果有父节点就要用父节点的takeChild删除节点
        delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());
    }
}

针对上方代码的完善

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

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

    // 设置QTreeWidget的列数
    ui->treeWidget->setColumnCount(1);
    // 设置QTreeWidget标题隐藏
    ui->treeWidget->setHeaderHidden(true);

    // 创建QTreeWidget的朋友节点,父节点是tree
    QTreeWidgetItem *Friend = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("朋友")));
    Friend->setIcon(0,QIcon(":/image/4.ico"));  // 添加一个图标
    Friend->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                     | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);

    // 给Friend添加一个子节点frd
    QTreeWidgetItem *frd = new QTreeWidgetItem(Friend);
    frd->setText(0,"老张");
    frd->setIcon(0,QIcon(tr(":/image/1.ico")));

    frd->setCheckState(0,Qt::Checked);

    QTreeWidgetItem *frs = new QTreeWidgetItem(Friend);
    frs->setText(0,"老王");
    frs->setIcon(0,QIcon(tr(":/image/1.ico")));

    frs->setCheckState(0,Qt::Unchecked);


    // ----------------------------------------------------------
    // 创建名叫同学节点,父节点同样是tree
    QTreeWidgetItem * ClassMate = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("同学")));
    ClassMate->setIcon(0,QIcon(":/image/5.ico"));  // 添加一个图标

    //Fly是ClassMate的子节点
    QTreeWidgetItem *Fly = new QTreeWidgetItem(QStringList(QString("张三")));
    Fly->setIcon(0,QIcon(tr(":/image/2.ico")));
    //创建子节点的另一种方法
    ClassMate->addChild(Fly);

    QTreeWidgetItem *Fls = new QTreeWidgetItem(QStringList(QString("李四")));
    Fls->setIcon(0,QIcon(tr(":/image/2.ico")));
    ClassMate->addChild(Fls);

    // ----------------------------------------------------------
    // 陌生人单独一栏
    QTreeWidgetItem  *Strange = new QTreeWidgetItem(true);
    Strange->setText(0,"陌生人");
    Strange->setIcon(0,QIcon(":/image/6.ico"));  // 添加一个图标

    ui->treeWidget->addTopLevelItem(ClassMate);
    ui->treeWidget->addTopLevelItem(Strange);

    //展开QTreeWidget的所有节点
    //ui->treeWidget->expandAll();
    //ui->treeWidget->resize(271,401);
}

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

QTreeWidgetItem * MainWindow::AddTreeRoot(QString name,QString desc)
{
    QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
    ui->treeWidget->addTopLevelItem(item);
    return item;
}

QTreeWidgetItem * MainWindow::AddTreeNode(QTreeWidgetItem *parent,QString name,QString desc)
{
    QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
    parent->addChild(item);
    return item;
}

// 当我们双击指定的成员时获取到该成员的名字
void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->text(column);
    std::cout << str.toStdString().data() << std::endl;
}

// 当我们单击指定成员时获取数据
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->text(column);
    std::cout << str.toStdString().data() << std::endl;
}

// 单击按钮添加新的父节点
void MainWindow::on_pushButton_clicked()
{
    QString NodeText = "新的父节点";
    QTreeWidgetItem  *item = new QTreeWidgetItem(true);
    item->setText(0,NodeText);
    item->setIcon(0,QIcon(":/image/7.ico"));
    ui->treeWidget->addTopLevelItem(item);
}

// 单击按钮添加子节点
void MainWindow::on_pushButton_4_clicked()
{
    QTreeWidgetItem * item= ui->treeWidget->currentItem();
        if(item!=NULL)
            AddTreeNode(item,"新子节点","新子节点");
        else
            AddTreeRoot("新子节点","新子节点");
}

// 单击后将指定节点修改为Modify并将图标设置为新的
void MainWindow::on_pushButton_2_clicked()
{
    // 得到当前节点
    QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
        return;
    // 修改选中项
    for(int x=0;x<currentItem->columnCount();x++)
    {
        currentItem->setText(x,tr("Modify") + QString::number(x));
        currentItem->setIcon(x,QIcon(":/image/1.ico"));
    }

}

// 删除选中的节点
void MainWindow::on_pushButton_3_clicked()
{
    QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
        return;

    // 如果没有父节点则直接删除
    if(currentItem->parent() == NULL)
    {
        delete ui->treeWidget->takeTopLevelItem(ui->treeWidget->currentIndex().row());
        std::cout << ui->treeWidget->currentIndex().row() << std::endl;
    }
    else
    {
        // 如果有父节点就要用父节点的takeChild删除节点
        delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());
    }
}

// 枚举所有节点
void MainWindow::on_pushButton_5_clicked()
{
    // 获取到全部的根节点数量
    int size = ui->treeWidget->topLevelItemCount();
    QTreeWidgetItem *child;
    for(int x=0;x<size;x++)
    {
        // 输出所有父节点
        child = ui->treeWidget->topLevelItem(x);
        std::cout << "all root = "<< child->text(0).toStdString().data() << std::endl;

        // 得到所有子节点计数
        int childCount = child->childCount();
        // std::cout << "all child count = " << childCount << std::endl;

        // 输出根节点下面的子节点
        for(int y=0;y<childCount;++y)
        {
            QTreeWidgetItem *grandson = child->child(y);

            if(Qt::Checked == grandson->checkState(0))
            {
                std::cout << "--> sub child = "<< grandson->text(0).toStdString().data() << std::endl;
            }

        }
    }
}

// 获取子节点的父节点ID,然后根据ID得到子节点名字
void MainWindow::on_pushButton_6_clicked()
{
    // 取所有的父节点
    QTreeWidgetItem *currentItem = ui->treeWidget->currentItem()->parent();
    int root_count = ui->treeWidget->indexOfTopLevelItem(currentItem);
    std::cout << "root Count = " <<  root_count << std::endl;
    if(root_count != -1)
    {
        // 指定序号对应的父节点名字
        QTreeWidgetItem *child;

        child = ui->treeWidget->topLevelItem(root_count);
        std::cout << "root name= "<< child->text(0).toStdString().data() << std::endl;
    }
}


图片组件的使用


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

    // 添加表头
    QStringList headers;
    headers.append("文件名称");
    headers.append("完整路径");
    ui->treeWidget->setHeaderLabels(headers);

    // 设置treeWidget属性
    ui->treeWidget->setColumnCount(2);         // 设置总列数
    ui->treeWidget->setIndentation(1);         // 设置表头缩进为1

    ui->label->setAlignment(Qt::AlignCenter);  // 设置label居中显示
}

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

// 从一个完整目录名称里,获得最后的文件夹名称
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(QString RelativePathName, QString FullPathName)
{
    QString NodeText=getFinalFolderName(FullPathName); //获得最后的文件名称
    QTreeWidgetItem *item; //节点

    // 新创建一个子节点
    item=new QTreeWidgetItem();
    item->setIcon(0,QIcon(":/image/1.ico"));
    item->setText(0,RelativePathName);
    item->setText(1,FullPathName);

    // 设置节点Qt::UserRole的Data,存储完整文件名称 需要注意我们存储的是1这个节点
    // 也就是完整路径中的内容,提取时也应该指定为1节点

    item->setData(0,Qt::UserRole,QVariant(RelativePathName));
    item->setData(1,Qt::UserRole,QVariant(FullPathName));
    ui->treeWidget->addTopLevelItem(item);
}

// 点击按钮批量导入图片资源
void MainWindow::on_pushButton_clicked()
{
    // 选择一个文件或多个
    QStringList file = QFileDialog::getOpenFileNames(this,"选择一个或多个文件","","Images(*.jpg)");

    // 判断是否为空,为空则返回
    if(file.isEmpty())
        return;

    // 循环添加新节点
    for(int x=0;x<file.size();++x)
    {
        QString FullPathName = file.at(x);
        QString RelativePathName = getFinalFolderName(FullPathName);
        std::cout << FullPathName.toStdString().data() << std::endl;
        std::cout << RelativePathName.toStdString().data() << std::endl;
        addImageItem(RelativePathName,FullPathName);
    }
}

// 点击按钮测试获取图片路径
void MainWindow::on_pushButton_2_clicked()
{
    QTreeWidgetItem* parItem=ui->treeWidget->currentItem(); //当前节点

    // 获取节点data里存的文件名,由于设置的是1节点,所以提取是必须也为1
    QString FullPathName = parItem->data(1,Qt::UserRole).toString();
    std::cout << "Full Name => " << FullPathName.toStdString().data() << std::endl;

    QString RelativePathName = parItem->data(0,Qt::UserRole).toString();
    std::cout << "Relative Name => " << RelativePathName.toStdString().data() << std::endl;
}

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

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

    // 显示到标签中
    ui->label->setPixmap(pix_height);   // 设置Label的PixMap 按高度调整
    //ui->label->setPixmap(pix_width);  // 按宽度调整
}

// 当图片被选中时默认自适应显示
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
    QString FilePath = item->data(column,Qt::UserRole).toString();
    std::cout << "FilePath = " << FilePath.toStdString().data() << std::endl;
    curPixmap.load(FilePath);
    on_actZoomFitH_triggered();
}

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

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

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

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

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

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

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

// 恢复默认值
void MainWindow::on_pushButton_5_clicked()
{
    pixRatio=1;  //恢复显示比例为1
    ui->label->setPixmap(curPixmap);
}


底部状态栏统计信息的添加 默认QT会生成,我们需要手动初始化一下即可使用。

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

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

    // 初始化状态栏
    labCellIndex = new QLabel("当前坐标: ",this);
    labCellIndex->setMinimumWidth(250);

    labCellType=new QLabel("单元格类型: ",this);
    labCellType->setMinimumWidth(200);

    labStudID=new QLabel("学生ID: ",this);
    labStudID->setMinimumWidth(200);

    // 将初始化的标签添加到底部状态栏上
    ui->statusbar->addWidget(labCellIndex);
    ui->statusbar->addWidget(labCellType);
    ui->statusbar->addWidget(labStudID);
}

// 当前选择单元格发生变化时触发响应事件,也就是将底部状态栏标签设置
void MainWindow::on_tableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
    Q_UNUSED(previousRow);
    Q_UNUSED(previousColumn);

    // 显示行与列的变化数值
    std::cout << "currentRow = " << currentRow << " currentColumn = " << currentColumn << std::endl;
    std::cout << "pre Row = " << previousRow << " pre Column = " << previousColumn << std::endl;

    // 获取当前单元格的Item
    QTableWidgetItem *item = ui->tableWidget->item(currentRow,currentColumn);
    std::cout << item << std::endl;
    if(item == NULL)
        return;

    // 设置单元格坐标
    labCellIndex->setText(QString::asprintf("当前坐标: %d 行 | %d 列",currentRow,currentColumn));

    // 设置单元格类型
    int cellType = item->type();
    labCellType->setText(QString::asprintf("单元格类型: %d",cellType));
}

循环设置表头元素

// 设置表头的实现
void MainWindow::on_pushButton_clicked()
{
    QTableWidgetItem *headerItem;
    QStringList headerText_Row,headerText_Col;
    headerText_Row << "姓 名" << "性 别" << "出生日期" << "民 族" << "分数" << "是否党员";
    headerText_Col << "第一行" << "第二行";

    // 设置为水平表头
    ui->tableWidget->setHorizontalHeaderLabels(headerText_Row);

    // 设置垂直表头
    ui->tableWidget->setVerticalHeaderLabels(headerText_Col);

    // 另一种方式: 通过循环设置
    ui->tableWidget->setColumnCount(headerText_Row.count());       // 列数设置为与headerText的行数相等
    for (int i=0;i<ui->tableWidget->columnCount();i++)             // 列编号从0开始
    {
       headerItem=new QTableWidgetItem(headerText_Row.at(i));      // headerText.at(i) 获取headerText的i行字符串
       QFont font=headerItem->font();                              // 获取原有字体设置
       font.setBold(true);                                         // 设置为粗体
       font.setPointSize(8);                                       // 设置字体大小
       headerItem->setTextColor(Qt::black);                        // 设置字体颜色
       headerItem->setFont(font);                                  // 设置字体
       ui->tableWidget->setHorizontalHeaderItem(i,headerItem);     // 设置表头单元格的Item
    }
}

设置初始化表格,行选择,列选择,单元格选择。

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

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->tableWidget->clear();
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

    // 初始化状态栏
    labCellIndex = new QLabel("当前坐标: ",this);
    labCellIndex->setMinimumWidth(250);

    labCellType=new QLabel("单元格类型: ",this);
    labCellType->setMinimumWidth(200);

    labStudID=new QLabel("学生ID: ",this);
    labStudID->setMinimumWidth(200);

    // 将初始化的标签添加到底部状态栏上
    ui->statusbar->addWidget(labCellIndex);
    ui->statusbar->addWidget(labCellType);
    ui->statusbar->addWidget(labStudID);
}

// 当前选择单元格发生变化时触发响应事件,也就是将底部状态栏标签设置
void MainWindow::on_tableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
    Q_UNUSED(previousRow);
    Q_UNUSED(previousColumn);

    // 显示行与列的变化数值
    std::cout << "currentRow = " << currentRow << " currentColumn = " << currentColumn << std::endl;
    std::cout << "pre Row = " << previousRow << " pre Column = " << previousColumn << std::endl;

    // 获取当前单元格的Item
    QTableWidgetItem *item = ui->tableWidget->item(currentRow,currentColumn);
    std::cout << item << std::endl;
    if(item == NULL)
        return;

    // 设置单元格坐标
    labCellIndex->setText(QString::asprintf("当前坐标: %d 行 | %d 列",currentRow,currentColumn));

    // 设置单元格类型
    int cellType = item->type();
    labCellType->setText(QString::asprintf("单元格类型: %d",cellType));
}

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

// 设置表头的实现
void MainWindow::on_pushButton_clicked()
{
    QTableWidgetItem *headerItem;
    QStringList headerText_Row,headerText_Col;
    headerText_Row << "姓 名" << "性 别" << "出生日期" << "民 族" << "分数" << "是否党员";
    headerText_Col << "第一行" << "第二行";

    // 设置为水平表头
    ui->tableWidget->setHorizontalHeaderLabels(headerText_Row);

    // 设置垂直表头
    //ui->tableWidget->setVerticalHeaderLabels(headerText_Col);

    // 另一种方式: 通过循环设置
    ui->tableWidget->setColumnCount(headerText_Row.count());       // 列数设置为与headerText的行数相等
    for (int i=0;i<ui->tableWidget->columnCount();i++)             // 列编号从0开始
    {
       headerItem=new QTableWidgetItem(headerText_Row.at(i));      // headerText.at(i) 获取headerText的i行字符串
       QFont font=headerItem->font();                              // 获取原有字体设置
       font.setBold(true);                                         // 设置为粗体
       font.setPointSize(8);                                       // 设置字体大小
       headerItem->setTextColor(Qt::black);                        // 设置字体颜色
       headerItem->setFont(font);                                  // 设置字体
       ui->tableWidget->setHorizontalHeaderItem(i,headerItem);     // 设置表头单元格的Item
    }
}

// 从spinBox中读出数量,并设置TableWidget表格的行数
void MainWindow::on_pushButton_2_clicked()
{
    // 读取出spinBox中的数据,并将其设置到表格中
    ui->tableWidget->setRowCount(ui->spinBox->value());

    // 行的底色交替采用不同颜色
    ui->tableWidget->setAlternatingRowColors(true);
}

// 设置表格是否可编辑
void MainWindow::on_checkBox_clicked(bool checked)
{
    if (checked)
        ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    else
        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允许编辑
}

// 行的底色交替采用不同颜色
void MainWindow::on_checkBox_2_clicked(bool checked)
{
    ui->tableWidget->setAlternatingRowColors(checked);
}

// 显示水平表头
void MainWindow::on_checkBox_3_clicked(bool checked)
{
    ui->tableWidget->horizontalHeader()->setVisible(checked);
}

// 显示垂直表头
void MainWindow::on_checkBox_4_clicked(bool checked)
{
    ui->tableWidget->verticalHeader()->setVisible(checked);
}

// 设置为单元格选择
void MainWindow::on_radioButton_clicked()
{
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectItems);
}

// 设置为行选择
void MainWindow::on_radioButton_2_clicked()
{
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
}

table表单的另一种尝试:

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

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

    QStringList header;
    header << "姓名" << "性别" << "年龄";

    ui->tableWidget->setColumnCount(header.size());                        // 设置表格的列数
    ui->tableWidget->setHorizontalHeaderLabels(header);                    // 设置水平头
    ui->tableWidget->setRowCount(5);                                       // 设置总行数
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);   // 设置表结构默认不可编辑

    // 初始化右侧的编辑框等属性
    ui->radioButton->setChecked(true);
    ui->lineEdit_1->setText("");
    ui->lineEdit_2->setText("");

    // 填充数据
    QStringList NameList;
    NameList << "张三" << "李四" << "王五";

    QStringList SexList;
    SexList << "男" << "男" << "女";

    qint32 AgeList[3] = {22,23,43};

    // 针对获取元素使用 NameList[x] 和使用 NameList.at(x)效果相同
    for(int x=0;x< 3;x++)
    {
        int col =0;
        // 添加姓名
        ui->tableWidget->setItem(x,col++,new QTableWidgetItem(NameList[x]));
        // 添加性别
        ui->tableWidget->setItem(x,col++,new QTableWidgetItem(SexList.at(x)));
        // 添加年龄
        ui->tableWidget->setItem(x,col++,new QTableWidgetItem( QString::number(AgeList[x]) ) );
    }

    // 给添加按钮绑定一个信号槽,点击按钮添加
    connect(ui->pushButton,&QPushButton::clicked,[=](){

        QString Uname = ui->lineEdit_1->text();
        QString Usex = "男";
        int Uage = 0;

        if(ui->radioButton->isChecked())
            Usex = "男";
        if(ui->radioButton_2->isChecked())
            Usex = "女";

        Uage =(ui->lineEdit_2->text()).toInt();

        // 添加之前,先判断Uname是否存在于TableWidget中,如果存在返回0不存在返回1
        bool isEmpty = ui->tableWidget->findItems(Uname,Qt::MatchExactly).empty();
        if(isEmpty)
        {
            ui->tableWidget->insertRow(0);    // 在行首添加一行空列表
            ui->tableWidget->setItem(0,0,new QTableWidgetItem(Uname));
            ui->tableWidget->setItem(0,1,new QTableWidgetItem(Usex));
            ui->tableWidget->setItem(0,2,new QTableWidgetItem( QString::number(Uage)));
        }
    });

    // 点击按钮删除选中行
    connect(ui->pushButton_2,&QPushButton::clicked,[=](){
        bool isEmpty = ui->tableWidget->findItems(ui->lineEdit_1->text(),Qt::MatchExactly).empty();
        if(!isEmpty)
        {
            // 定位到所在行行号
            int row = ui->tableWidget->findItems(ui->lineEdit_1->text(),Qt::MatchExactly).first()->row();
            // 释放资源
            ui->tableWidget->removeRow(row);
        }
    });

    // 获取当前选中单元,并释放当前单格
    connect(ui->pushButton_3,&QPushButton::clicked,[=](){
        int row = ui->tableWidget->currentRow();
        std::cout << row << std::endl;

        QTableWidgetItem *table =  ui->tableWidget->currentItem();
        delete(table);
    });

    // 添加修改指定内容的处理流程
    connect(ui->pushButton_4,&QPushButton::clicked,[=](){
        QTableWidgetItem *cellItem;

        // 取出当前选中行
        int curr_row = ui->tableWidget->currentRow();

        // 循环列数
        for(int col=0; col<ui->tableWidget->columnCount(); col++)
        {
            // 寻找到当前列的指针
            cellItem = ui->tableWidget->item(curr_row,col);

            // 循环输出列名称
            std::cout << cellItem->text().toStdString().data() << std::endl;

            // 先来处理第一个姓名,读出来并写回到列表第0列
            if(col == 0)
                cellItem->setText(ui->lineEdit_1->text());

            // 判断性别,并分别写回到第1列
            if(col == 1)
            {
                if(ui->radioButton->isChecked())
                    cellItem->setText("男");
                if(ui->radioButton_2->isChecked())
                    cellItem->setText("女");
            }

            // 判断年龄,并写回到第3列
            if(col == 2)
                cellItem->setText(ui->lineEdit_2->text());
        }
    });
}

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

posted @ 2020-11-26 20:05  lyshark  阅读(95)  评论(0编辑  收藏