Qt第三课 ----------多元素控件

作者前言

🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
​🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者id:老秦包你会, 🎂
简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
喜欢学习C语言、C++和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
🎂个人主页::小小页面🎂
🎂gitee页面:秦大大🎂
🎂🎂🎂🎂🎂🎂🎂🎂
🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂


简单介绍

Qt 中提供的多元素控件有:
QListWidget
• QListView
• QTableWidget
• QTableView
• QTreeWidget
• QTreeView
简单的将其分为 列表(QListWidget、 QListView) ,表格(QTableWidget、QTableView)以及树(QTreeWidget、QTreeview)
widget和view的区别
以 QTableWidget 和 QTableView 为例.
• QTableView 是基于 MVC 设计的控件. QTableView ⾃⾝不持有数据. 使⽤ QTableView 的
时候需要⽤⼾创建⼀个 Model 对象 (⽐如 QStandardModel ), 并且把 Model 和
QTableView 关联起来. 后续修改 Model 中的数据就会影响 QTableView 的显⽰; 修改
QTableView 的显⽰也会影响到 Model 中的数据(双向绑定).
• QTableWidget 则是 QTableView 的⼦类, 对 Model 进⾏了封装. 不需要⽤⼾⼿动创建
Model 对象, 直接就可以往 QTableWidget 中添加数据了
如图:
在这里插入图片描述

MVC的介绍:
MVC 拆解成如下:
model (数据)、 view(视图界面)、controller(控制器,用于数据和视图的流程 ,简称媒介)
这里的view只是负责了视图的界面,不负责数据的存储和传输以及交互,如果使用view,需要程序员自己去实现model和controller这部分,
所以说widget就是基于view实现了model和controller这部分
好比我们需要买一台电脑, 方法1是自己买零件自己组装view就好比电脑的零件, 方法2就是直接买一台已经组装好的电脑,

List Widget

属性如下:
在这里插入图片描述
在这里插入图片描述

信号函数
在这里插入图片描述
下面写一个列表, 可以添加和删除内容的listwidget
代码如下:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建一个列表
    QListWidget* list = new QListWidget(this);
    // 创建一个单行输入
    QLineEdit * line = new QLineEdit(this);
    line->setPlaceholderText("输入要添加的内容");
    line->move(list->x()+list->width()+200, 0);
    //添加按钮
    QPushButton *addButton = new QPushButton("添加", this);
    ButtonPostion(addButton, line->x(), line->y()+line->height()+20);
    //删除按钮
    QPushButton *deleteButton = new QPushButton("删除", this);
     ButtonPostion(deleteButton, addButton->x(), addButton->y()+addButton->height()+20);
    connect(addButton, &QPushButton::clicked, this, [=]()
    {

        list ->addItem(new QListWidgetItem(line->text(),list));
        qDebug()<< list->count();
        qDebug()<< "添加的元素为:" << line->text();
        line->setText("");

    });
    connect(deleteButton, &QPushButton::clicked, this, [=]()
    {
        QListWidgetItem * ret = nullptr;
        if(list->currentItem())
        {
            ret = list->takeItem(list->currentRow());
        }
        else if(list->count()!=0)
            ret = list ->takeItem(list->count()-1);
        qDebug()<< list->count();
        if(ret)
            qDebug()<< "删除的元素为:" << ret->text();

    });
}
void Widget::ButtonPostion(QPushButton *button, int x, int y) const
{
    button->move(x,y);
}

效果如下:
在这里插入图片描述
如果我们要写一个listview的代码,上面的代码是可以更改的,但是我们更改会比较困难,因为view只是一个显示的界面, 不能完成数据的计算,添加的内容和删除的内容,就需要我们一个个的去写代码,去计算, 使用listwidget就省略这些步骤,

Table Widget

使⽤ QTableWidget 表⽰⼀个表格控件,⼀个表格中包含若⼲⾏, 每⼀⾏⼜包含若⼲列.表格中的每个单元格, 是⼀个 QTableWidgetItem 对象.
属性如下:
在这里插入图片描述

在这里插入图片描述
信号函数:
cellClicked(int row, int column) 点击单元格时触发
cellDoubleClicked(int row, int column)双击单元格时触发
cellEntered(int row, int column) ⿏标进⼊单元格时触发
currentCellChanged(int row, int column, int previousRow, int previousColumn)

下面我们写一个代码,用来控制TableWidget的增删改查

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建一个表格
    sheet = new QTableWidget(this);
    sheet->setFixedSize(300,600);
    //创建四个lineEdit
    rowline = CreateLineEdit(sheet->x()+sheet->width()+200, sheet->y(), "输入行数");
    columnline = CreateLineEdit(rowline->x()+rowline->width()+200,rowline->y(), "输入列数");
    Verticalheader = CreateLineEdit(rowline->x(),rowline->y()+ rowline->width()+200, "输入行头");
    Horizontalheader = CreateLineEdit(Verticalheader->x()+Verticalheader->width()+200,Verticalheader->y(), "输入列头");
    //创建增加行按钮
    addRowButton = CreatePushButton(rowline->x()+rowline->width(), rowline->y()+rowline->height()+50, "添加行", &Widget::addRowSlot);
    //创建删除行按钮
    deleteRoeButton = CreatePushButton(addRowButton->x()+addRowButton->width()+50, addRowButton->y(), "删除行",&Widget::deleteRowSlot);
    //创建添加列按钮
    addColumnButton = CreatePushButton(addRowButton->x(), addRowButton->y()+addRowButton->height()+50, "添加列", &Widget::addColumnSlot);
    //创建删除列按钮
    deleteColumnButton = CreatePushButton(addColumnButton->x()+addColumnButton->width()+50, addColumnButton->y(), "删除列",&Widget::deleteColumnSlot);
    //添加内容
    addValueButton =  CreatePushButton(addColumnButton->x(), addColumnButton->y()+addColumnButton->height()+50, "添加内容",&Widget::addValue);
    //删除内容
    deleteValueButton = CreatePushButton(addValueButton->x()+addValueButton->width()+50, addValueButton->y(), "删除内容",&Widget::deleteValue);
    //添加列头
    addHorizontalheaderButton = CreatePushButton(Horizontalheader->x(), Horizontalheader->y()+ Horizontalheader->height()+50, "增加列头",&Widget::addHorizontalValue);
    //添加行头
    addVerticalheaderButton = CreatePushButton(Verticalheader->x(), Verticalheader->y()+Verticalheader->height()+50, "增加行头",&Widget::addVetticalValue);
    //    qDebug()<< rowline->x() << rowline->width() << addButton->pos();

    //设置选中单元格的信号和槽
    connect(sheet, &QTableWidget::cellClicked, this, [=](int row, int column)
    {

        rowline->setText(QString::number(row+1));
        columnline->setText(QString::number(column+1));

    });


}

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

QLineEdit *Widget::CreateLineEdit(int x, int y, QString value)
{
    QLineEdit *rowline = new QLineEdit(this);
    rowline->move(x, y);
    rowline->setPlaceholderText(value);
    return rowline;
}

QPushButton *Widget::CreatePushButton(int x, int y, QString value, void (Widget::*funtion)() ,int width, int heigth)
{
    QPushButton *addButton = new QPushButton(value, this);
    addButton->setFixedSize(100,30);
    addButton->move(x,y);
    connect(addButton,&QPushButton::clicked, this,funtion);
    return addButton;
}

void Widget::addRowSlot()
{
    qDebug()<< "addRowSlot";
    //获取当前的选择的行,如果没有就在后面插入
    if(sheet->currentRow()< 0)//为选择要判断, 一种是行为空,一种是没空
    {

        sheet->insertRow(sheet->rowCount());
    }
    else
    {
        sheet->insertRow(sheet->currentRow());
    }

    qDebug()<< sheet->rowCount();
}

void Widget::deleteRowSlot()
{
    qDebug()<< "deleteRowSlot" ;
    if(sheet->currentRow()>= 0)
        sheet->removeRow(sheet->currentRow());
    else
        sheet->removeRow(sheet->rowCount()-1);//

}

void Widget::addColumnSlot()
{
    qDebug()<< "deleteRowSlot";
    //获取当前的选择的列,如果没有就在后面插入
    if(sheet->currentColumn()< 0)
    {
        sheet->insertColumn(sheet->columnCount());
    }
    else
    {
        sheet->insertColumn(sheet->currentColumn());
    }
}

void Widget::deleteColumnSlot()
{
    qDebug()<< "deleteColumnSlot";
    if(sheet->currentColumn()>= 0)
        sheet->removeColumn(sheet->currentColumn());
    else
        sheet->removeColumn(sheet->columnCount()-1);//

}

void Widget::addValue()
{
    qDebug()<< "addValue";
    if(sheet->rowCount() >=rowline->text().toInt()&& sheet->columnCount()>= columnline->text().toInt())
        sheet->setItem(rowline->text().toInt()-1, columnline->text().toInt()-1, new QTableWidgetItem("111"));

}

void Widget::deleteValue()
{
    qDebug()<< "deleteValue";
    if(rowline->text().isEmpty()&&columnline->text().isEmpty())
            return;
    if(sheet->rowCount() >=rowline->text().toInt()&& sheet->columnCount()>= columnline->text().toInt())
       if(sheet->item(rowline->text().toInt()-1, columnline->text().toInt()-1))
           sheet->item(rowline->text().toInt()-1, columnline->text().toInt()-1)->setText("");




}

void Widget::addHorizontalValue()
{
    if(columnline->text().isEmpty())
        return;
    sheet->setHorizontalHeaderItem(columnline->text().toInt()-1,new QTableWidgetItem  (Horizontalheader->text()));
    qDebug()<< "addHorizontalValue" << Horizontalheader->text();
}

void Widget::addVetticalValue()
{
    if(rowline->text().isEmpty())
        return;
    sheet->setVerticalHeaderItem(rowline->text().toInt()-1,new QTableWidgetItem (Verticalheader->text()));
    qDebug()<< "addVetticalValue";
}

效果图:
在这里插入图片描述

一般情况下,我们是要通过读取文件或者网络获取数据的,不会傻乎乎的去手动添加,所以的我们可以去找一个Excel表格来进行内容的读取进行操作,这里的话就不演示了

Treewidget

使⽤ QTreeWidget 表⽰⼀个树形控件. ⾥⾯的每个元素, 都是⼀个 QTreeWidgetItem , 每个
QTreeWidgetItem 可以包含多个⽂本和图标, 每个⽂本/图标为⼀个 列
可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加⼦节点, 从⽽构成树形结构.
属性如下:
在这里插入图片描述
信号函数如下:
currentItemChanged(QTreeWidgetItem*
current, QTreeWidgetItem* old) 切换选中元素时触发
itemClicked(QTreeWidgetItem* item, int col) 点击元素时触发
itemDoubleClicked(QTreeWidgetItem* item, int col)双击元素时触发
itemEntered(QTreeWidgetItem* item, int col) ⿏标进⼊时触发
itemExpanded(QTreeWidgetItem* item) 元素被展开时触发
itemCollapsend(QTreeWidgetItem* item) 元素被折叠时触发

QTreeWidgetItem

这个是treewidget的节点对象类型, 和前面的listwidget的listwidhetItem以及tablewidget的tablewidgetitem是一样的情况,也有属于自己的函数, 下面列举一下,
在这里插入图片描述
addChild(QTreeWidgetItem* child) 新增⼦节点
childCount() ⼦节点的个数
child(int index) 获取指定下标的⼦节点. 返回 QTreeWidgetItem*
takeChild(int index) 删除对应下标的⼦节点
removeChild(QTreeWidgetItem*child) 删除对应的⼦节点
parent() 获取该元素的⽗节点

下面我们采用图形化的方式创建一个简单的界面, 然后在界面上进行操作, 进行顶点和子节点的创建和删除
ui文件:
在这里插入图片描述
代码如下:

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

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


void Widget::on_pushButton_clicked()
{
    QString value= ui->lineEdit->text();
    QStringList heade(value);
    ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(heade));
    ui->lineEdit->setText("");

}

void Widget::on_pushButton_2_clicked()
{
    QString value= ui->lineEdit->text();
    QStringList heade(value);
    //获取当前的节点
    ui->treeWidget->currentItem()->addChild(new QTreeWidgetItem(heade));
}

void Widget::on_pushButton_3_clicked()
{
    //获取当前的节点,并返回当前顶点在所有顶点的下标
    QTreeWidgetItem * curren = ui->treeWidget->currentItem();
    if(curren!= nullptr)
    {
        int index = ui->treeWidget->indexOfTopLevelItem(curren);
        ui->treeWidget->takeTopLevelItem(index);
    }

}

void Widget::on_pushButton_4_clicked()
{
    //需要判断当前节点是否是顶点, 如果不是直接删除, 如果是删除顶点
    //获取当前的节点
    QTreeWidgetItem * curren = ui->treeWidget->currentItem();
    QTreeWidgetItem * parent = nullptr;
    if(curren)
        parent =  curren->parent();
    if(parent == nullptr)
        on_pushButton_3_clicked();
    else
    {
        parent->removeChild(ui->treeWidget->currentItem());
    }

}

效果如下:
在这里插入图片描述
可以看出,这个效果出编译完成出来, 是有一个根节点的,跟我们认识的不太一样,
在这里插入图片描述

这里的顶层节点不是根节点,而是根节点的孩子节点,如果觉得根节点的内容不好看,可以使用headerlabel函数去更改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老秦包你会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值