Qt 输入与多元素控件详解

1.输入类控件

1.1 Line Edit

  • QLineEdit用来表示单行输入框,可以输入一段文本,但是不能换行
  • 属性:
    • text:输入款中的文本
    • inputMask:输入内容格式约束
    • maxLength:最大长度
    • frame:是否添加边框
    • echoMode:显示方式
      • QLineEdit::Normal:默认值,文本框会显示输入的文本
      • QLineEdit::Password:输入的字符会被隐藏,通常用*或=代替
      • QLineEdit::NoEcho:文本框不会显示任何输入的字符
    • cursorPosition:光标位置
    • alignment:对齐方式
    • dragEnabled:是否允许拖拽
    • readOnly:是否是只读的
    • placeHolderText:输入框为空时,显示什么信息
    • clearButtonEnabled:是否自动显示"清除"按钮
  • 核心信号
    • void cursorPositionChanged(int old,int new)
      • 鼠标移动时发出此信号,old为旧位置,new为新位置
    • void editingFinished()
      • 当按返回或者回车键时,或者行编辑失去焦点时,发出此信号
    • void returnPressed()
      • 当返回或回车键按下时发出此信号。如果设置了验证其,必须要验证通过才能触发
    • void selectionChanged()
      • 当选中的文本改变时,发出此信号
    • void textChanged(const QString &text)
      • 当QLineEdit中的文本改变时,发出此信号,text是新文本;代码对文本的修改能够触发此信号
    • void textEdited(Qstring &text)
      • 当QLineEdit中的文本改变时,发出此信号,text是新文本;代码对文本的修改不能触发此信号
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 初始化第一个输入框,用来输入姓名
    ui->lineEdit_name->setPlaceholderText("请输入姓名");
    ui->lineEdit_name->setClearButtonEnabled(true);

    // 初始化第二个输入款,用来输入密码
    ui->lineEdit_name_password->setPlaceholderText("请输入密码");
    ui->lineEdit_name_password->setClearButtonEnabled(true);
    // 把显示模式设置为密码格式
    ui->lineEdit_name_password->setEchoMode(QLineEdit::Password);

    // 初始化第三个输入款
    ui->lineEdit_name_phone->setPlaceholderText("请输入电话密码");
    ui->lineEdit_name_phone->setClearButtonEnabled(true);
    // 手机号码是有固定格式的,此处的0表示一个数字
    ui->lineEdit_name_phone->setInputMask("000-0000-0000");
}

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

void Widget::on_pushButton_submit_clicked()
{
    QString gender=ui->radioButton_male->isChecked()?"男":"女";
    qDebug()<<"姓名:"<<ui->lineEdit_name->text()
             <<"密码:"<<ui->lineEdit_name_password->text()
             <<"姓名:"<<gender
             <<"电话:"<<ui->lineEdit_name_phone->text();
}

1.1.1 正则表达式进行格式约束

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 需要给单行输入框设置验证器,基于正则表达式来实现
    QRegExp regExp("^1\\d{10}");
    // ^1表示以1开头;\d表示数字,为了在C++字符串中使用,需要写作\\d;{10}表示前面的内容重复出现10次
    ui->lineEdit->setValidator(new QRegExpValidator(regExp)); // 只是注册了一个验证器
}

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

void Widget::on_lineEdit_textEdited(const QString &text)
{
    // 第一个参数是要验证的字符串,参数类型是 QString&,不是const
    QString content=text;
    int pos=0;
    if(ui->lineEdit->validator()->validate(content,pos))   // 验证是否符合要求
    {
        // 验证通过
        ui->pushButton->setEnabled(true);
    }else{
        ui->pushButton->setEnabled(false);
    }
}

1.1.2 验证两次输入的密码是否一致

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 初始化,把这两个输入框的echoMode设置一下
    ui->lineEdit->setEchoMode(QLineEdit::Password);
    ui->lineEdit_2->setEchoMode(QLineEdit::Password);

    ui->label->setText("密码为空");
}

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

void Widget::compare()
{
    const QString s1=ui->lineEdit->text();
    const QString& s2=ui->lineEdit_2->text();
    if(s1.isEmpty() && s2.isEmpty()){
        ui->label->setText("密码为空");
    }else if(s1==s2){
        ui->label->setText("两次输入的密码一致");
    }else{
        ui->label->setText("两次输入的密码不一致");
    }
}

void Widget::on_lineEdit_textEdited(const QString &arg1)
{
    (void)arg1; // 处理未使用警告
    this->compare();
}

void Widget::on_lineEdit_2_textEdited(const QString &arg1)
{
    (void)arg1;
    this->compare();
}

2.1.3 切换密码状态

cpp 复制代码
void Widget::on_checkBox_toggled(bool checked)
{
    if(checked)
    {
        // true则是"显示密码"状态,就把输入框的显示模式,设为Normal
        ui->lineEdit->setEchoMode(QLineEdit::Normal);
    }else{
        ui->lineEdit->setEchoMode(QLineEdit::Password);
    }
}

1.2 TextEdit

  • QTextEdit表示多行输入框,也是一个富文本 &markdown 编辑器
  • 能在内容超出编辑框范围时自动提供滚动条
  • 属性:
    • markdown:输入框内持有的内容;支持 markdown 格式,能够自动对 markdown 文本进行渲染成 html
    • html:输入框内持有的内容,可以支持大部分 html 标签,包括 img 和 table 等
    • placeHolderText:输入框为空时提示的内容
    • readOnly:是否是只读
    • undoRedoEnable:是否开启 undo/redo 功能,按下 ctrl+z 触发 undo(撤销),按下 ctrl+y 触发 redo(撤销undo)
    • autoFormating:开启自动格式化
    • tabstopWidth:按下缩进占多少空间
    • overwriteMode:是否开启覆盖写(会把后面的数据覆盖掉)模式
    • acceptRichText:是否接收富文本格式
    • verticalScrollBarPolicy:垂直方向滚动条的出现策略
      • Qt::ScrollBarAsNeeded:根据内容自动决定是否需要滚动条,是默认的
      • Qt::ScrollBarAlwaysOff:总是关闭滚动条
      • Qt::ScrollBarAlwaysOn:总是显示滚动条
    • horizontalScrollBarPolicy:水平方向滚动条的出现策略
      • Qt::ScrollBarAsNeeded:根据内容自动决定是否需要滚动条,是默认的
      • Qt::ScrollBarAlwaysOff:总是关闭滚动条
      • Qt::ScrollBarAlwaysOn:总是显示滚动条
  • 核心信号:
    • textChanged():文本内容改变时触发
    • selectionChanged():选中范围改变时触发
    • cursorPositionChanged():光标移动时触发
    • undoAvaliable(bool):可以进行 undo 操作时触发
    • redoAvailable(bool):可以进行 redo 操作时触发
    • copyAvailable(bool):文本被选中/取消选中时触发
cpp 复制代码
void Widget::on_textEdit_textChanged()
{
    qDebug()<<"textChanged: "<<ui->textEdit->toPlainText();
}

void Widget::on_textEdit_selectionChanged()
{
    QTextCursor cursor=ui->textEdit->textCursor();
    qDebug()<<"selectionChanged: "<<cursor.selectedText();
}

void Widget::on_textEdit_cursorPositionChanged()
{
    QTextCursor cursor=ui->textEdit->textCursor();
    qDebug()<<"cursorPositionChanged: "<<cursor.position();
}

void Widget::on_textEdit_undoAvailable(bool b)
{
    qDebug()<<"undoAvailable: "<<b;
}

void Widget::on_textEdit_redoAvailable(bool b)
{
    qDebug()<<"redoAvailable: "<<b;
}

void Widget::on_textEdit_copyAvailable(bool b)
{
    qDebug()<<"copyAvailable: "<<b;
}

1.3 QComboBox

  • QComboBox 表示下拉框
  • 属性
    • currentText:当前选中的文本
    • currentIndex:当前选中的条目下标,从0开始计算,没有被选中的条目则为-1
    • editable:是否允许修改
    • iconSize:下拉框图标(小三角)大小
    • maxCount:最多允许有多少个条目
  • 核心方法:
    • addItem(const QString&):添加一个条目
    • currentIndex():获取当前条目的下标
    • currentText():获取当前条目的文本内容
  • 核心信号:
    • activated(int)/activated(const QString &text):
      • 当用户选择了一个选项时发出
      • 相当于用户点开下拉框,并且鼠标划过某个选项,此时还没有确认做出选择
    • currentIndexChanged(int)/currentIndexChanged(const QString& text):
      • 当前选项改变时发出
      • 用户已经明确的选择了一个选项
    • editTextChanged(const QString& text):
      • 当编辑框中的文本改变时发出(editable为true时有效)
cpp 复制代码
    // 读取文件内容,把文件中的每一行读取出来,作为一个 ComboBox 的选项
    std::ifstream file("C:\\Users\\28714\\Desktop\\config.txt");
    if(!file.is_open()){
        qDebug()<<"文件打开失败";
        return;
    }
    // 按行来读取文本内容
    // getline 函数
    std::string line;
    while(std::getline(file,line)){
        // 取到每一行的内容,设置到下拉框中
        ui->comboBox->addItem(QString::fromStdString(line));
    }
    file.close();

1.4 Spin Box

  • 使用 QSpinBox(存的是整数) 或者 QDoubleSpinBox(存的是小数) 表示=="微调框"==,他是带有按钮的输入框,可以用来输入整数/浮点数,通过点击按钮来修改数值大小
  • 属性
    • value:存储的数值
    • singleStep:按一次按钮数据变化多少
    • displayInteger:数字的进制
    • minimum:最小值
    • maximum:最大值
    • suffix:后缀
    • prefix:前缀
    • wrapping:是否允许换行
    • frame:是否带边框
    • alignment:文字对齐方式
    • readOnly:是否允许修改
    • buttonSymbol:按钮上的图标
      • UpDownArrows:上下箭头形式
      • PlusMinus:加减号形式
      • NoButtons:没有按钮
    • accelerated:按下按钮时是否为快速调整模式
    • correctionMode:输入有误时是否修正
      • QAbstractSpinBox::CorrectToPreviousValue:输入无效之后会恢复为上一个有效值
      • QAbstractSpinBox::CorrectToNearestValue:输入无效后恢复为最接近的有效值
    • keyboardTrack:是否开启键盘追踪
      • true:输入一个数字就会触发依次 valueChanged() 和 textChanged()
      • false:只有按下 enter 或输入框失去焦点才会触发 valueChanged() 和 textChanged()
  • 核心信号:
    • textChanged(QString):微调框的文本发生改变时会触发
    • valueChanged(int) :微调框的数值发生改变时会触发
cpp 复制代码
    // 针对 QSpinBox 的范围进行限制
    ui->spinBox->setRange(1,5);
    ui->spinBox_2->setRange(1,5);
    ui->spinBox_3->setRange(1,5);
	
	// 设置初始值
    ui->spinBox->setValue(1);
    ui->spinBox_2->setValue(1);
    ui->spinBox_3->setValue(1);

1.5 Date Edit & Time Edit

  • 使用 QDateEdit 作为日期的微调框
  • 使用 QTimeEdit 作为时间日期的微调框
  • QDateTimeEdit 核心属性
    • dateTime:时间日期的值,形如 2000/1/1 0:00:00
    • date:单纯日期的值,形如 2000/1/1
    • time:单纯时间的值,形如 0:00:00
    • displayFormat:时间日期格式,形如 yyyy/M/d H:mm
      • y 表示年份
      • M 表示月份
      • d 表示日期
      • H 表示小时
      • m 表示分钟
      • s 表示秒
      • 不同标准表示不同,不需要背
    • minimumDateTime:最小时间日期
    • maximumDateTime:最大时间日期
    • timeSpec:
      • Qt::LocalTime:显示本地时间
      • Qt::UTC:显示协调世界时(UTC)
      • Qt::OffsetFromUTC:显示相对于 UTC 的偏移量(时差)
  • 核心信号
    • dateChanged(QDate):日期改变时触发
    • timeChanged(QTime):时间改变时触发
    • dateTimeChanged(QDateTime):时间和日期任意一个改变时触发
  • 函数
    • daysTo:计算两个日期的日期的差值
    • secsTo:计算两个时间的秒数的差值
cpp 复制代码
void Widget::on_pushButton_clicked()
{
    // 1.先获取到两个输入框之间的时间都是啥
    QDateTime timeOld=ui->dateTimeEdit->dateTime();
    QDateTime timeNew=ui->dateTimeEdit_2->dateTime();
    qDebug()<<timeOld<<timeNew;
    // 2.计算日期差值
    int seconds=timeOld.secsTo(timeNew);
    // 3.把秒数换算成小时
    int hours=(seconds/3600)%24;    // 重点关心多出来的零头
    int days=(seconds/3600)/24;
    // 4.把计算结果放到label中
    ui->label->setText(QString("我已经学习了 ")+QString::number(days)+
                       QString(" 天零 ")+QString::number(hours)+QString(" 小时"));
}

1.6 Dial

  • QDial 表示一个旋钮
  • 核心属性
    • value:持有的数量
    • minimum:最小值
    • maximum:最大值
    • singleStep:按下方向键的时候改变的步长
    • pageStep:按下 pageUp/pageDown 的时候改变的步长
    • sliderPosition:界面上旋钮显示的初始位置
    • tracking:外观是否会跟踪数值变化,默认为true
    • wrapping:是否允许循环调整
    • notchesVisible:是否显示刻度线
    • notchTarget:刻度线之间的相对位置,数字越大,刻度线越稀疏
cpp 复制代码
void Widget::on_dial_valueChanged(int value)
{
    qDebug()<<value;
    this->setWindowOpacity((double)value/100);
}

1.7 Slider

  • 使用 QSlider 表示一个滑动条
  • 核心属性
    • value:持有的数量
    • minimum:最小值
    • maximum:最大值
    • singleStep:按下方向键的时候改变的步长
    • pageStep:按下 pageUp/pageDown 的时候改变的步长
    • sliderPosition:界面上滑动条显示的初始位置
    • tracking:外观是否会跟踪数值变化,默认为true
    • orientation:滑动条的方向时水平还是垂直
    • invertedApperance:是否要翻转滑动条的方向
    • tickPosition:刻度的位置
    • tickInterval:刻度的密集程度
  • 核心信号
    • valueChanged(int):数值改变时触发
    • rangeChanged(int,int):范围变化时触发

1.7.1 通过滑动条改变窗口大小

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->horizontalSlider->setMinimum(100);
    ui->horizontalSlider->setMaximum(2000);
    ui->horizontalSlider->setValue(800);
    ui->horizontalSlider->setSingleStep(50);

    ui->verticalSlider->setMinimum(100);
    ui->verticalSlider->setMaximum(1500);
    ui->verticalSlider->setValue(600);
    ui->verticalSlider->setSingleStep(50);
}

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

void Widget::on_horizontalSlider_valueChanged(int value)
{
    const QRect& rect=this->geometry();
    this->setGeometry(rect.x(),rect.y(),value,rect.height());
}

void Widget::on_verticalSlider_valueChanged(int value)
{
    const QRect& rect=this->geometry();
    this->setGeometry(rect.x(),rect.y(),rect.width(),value);
}

1.7.2 设置快捷键改变滑动条数值

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 使用快捷键,需要用到 QShortCut 类
    QShortcut* shortCut1=new QShortcut(this);
    shortCut1->setKey(QKeySequence("-"));
    QShortcut* shortCut2=new QShortcut(this);
    shortCut2->setKey(QKeySequence("+"));

    // 使用信号槽,感知到快捷键被按下
    connect(shortCut1,&QShortcut::activated,this,&Widget::subValue);
    connect(shortCut2,&QShortcut::activated,this,&Widget::addValue);
}

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

void Widget::on_horizontalSlider_valueChanged(int value)
{
    ui->label->setText("当前值为:"+QString::number(value));
}

void Widget::subValue()
{
    // 获取到当前的值
    int value=ui->horizontalSlider->value();
    if(value<=ui->horizontalSlider->minimum())
        return;
    ui->horizontalSlider->setValue(value-5);
}

void Widget::addValue()
{
    // 获取到当前的值
    int value=ui->horizontalSlider->value();
    if(value>=ui->horizontalSlider->maximum())
        return;
    ui->horizontalSlider->setValue(value+5);
}

2. 多元素控件

  • Qt 中提供的多元素控件有多种
    • 列表:
      • QListWidget
      • QListView
    • 表格:
      • QTableWidget
      • QTableView
    • 树形:
      • QTreeWidget
      • QTreeView
    • xxWidget 是 xxView 封装实现的,xxView 是更底层的实现
  • MVC结构
    • M:model 数据
    • V:view 视图
    • C:controller 控制器,数据和视图之间的业务流程
    • xxView 是 MVC 结构的一种典型实现,此处 xxView 只是负责实现了视图,不负责数据如何存储表示,更不负责数据和视图之间的交互。因此使用 xxView 需要程序员自己实现 model 和 controller 的部分,比较麻烦

2.1 QListWidget

  • 使用 QListWidget 能够显示一个纵向的列表
  • 核心属性
    • currentRow:当前被选中的是第几行
    • count:一共有多少行
    • sortingEnabled:是否允许排序
    • isWrapping:是否允许换行
    • itemAlignment:元素的对齐方式
    • selectRectVisible:被选中的元素矩形是否可见
    • spacing:元素之间的间隔
  • 核心方法:
    • addItem(const QString& label)/addItem(QListWidgetItem* item):添加元素
    • currentItem():返回当前选中的元素
    • setCurrentItem(QListWidgetItem* item):设置选中那个元素
    • setCurrentRow(int row):设置选中第几行的元素
    • insertItem(const QString& label,int row)/insertItem(QListWidgetItem* item,int row):在指定的位置插入元素,row 表示插入完毕之后新的元素在第几行,把新元素插入到第几行之前
    • item(int row):返回 QListWidgetItem* 表示第 row 行的元素
    • takeItem(int row):删除指定行的元素,返回 QListWidgetItem* 表示是哪个元素被删除了
  • 核心信号:
    • currentItemChanged(QListWidgetItem* current,QListWidgetItem* old):选中不同元素时触发,参数是当前选中的元素和之前选中的元素
    • currentEowChanged(int):选中不同元素时触发,参数是当前选中元素的行数
    • itemClicked(QListWidgetItem* item):点击某个元素时触发
    • itemDoubleClicked(QListWidgetItem* item):双击某个元素时触发
    • itemEntered(QListWidgetItem* item):鼠标进入元素时触发
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 往里面添加一些元素
    ui->listWidget->addItem("C++");
    ui->listWidget->addItem("Java");
    ui->listWidget->addItem("Python");
    ui->listWidget->addItem(new QListWidgetItem("Go"));
}

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

void Widget::on_pushButton_insert_clicked()
{
    const QString& text=ui->lineEdit->text();
    ui->listWidget->addItem(text);
}

void Widget::on_pushButton_delete_clicked()
{
    int row=ui->listWidget->currentRow();
    if(row<0)
        return;
    ui->listWidget->takeItem(row);
}

void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    // 通过这个槽函数,感知到变化
    if(current!=nullptr)
    {
        qDebug()<<"当前选中的元素:"<<current->text();
    }
    if(previous!=nullptr)
    {
        qDebug()<<"上次选中的元素:"<<previous->text();
    }
}

2.2 Table Widget

  • 使用 QTableWidget 表示一个表格控件,一个表格中包含若干行,每行包含若干列
  • 每个单元格是一个 QTableWidgteItem 对象
  • 核心方法
    • item(int row,int column):根据行数列数获取指定的 QTableWidgetItem*
    • setItem(int row,int column,QTableWidget*):根据行数列数设置表格中的元素
    • currentItem():返回被选中的元素 QTableWidgetItem*
    • currentRow():返回被选中元素是第几行
    • currentColumn():返回被选中元素是第几列
    • row(QTableWidgetItem*):获取指定 item 是第几行
    • column(QTableWidgetItem*):获取指定 item 是第几列
    • rowCount():获取行数
    • columnCount():获取列数
    • insertRow(int row):在第 row 行处插入新行
    • insertColumn(int column):在第 column 列插入新列
    • removeRow(int row):删除第 row 行
    • removeColumn(int column):删除第 column 列
    • setHorizontalHeaderItem(int column,QTableWidget*):设置指定列的表头
    • setVerticalHeaderItem(int row,QTableWidget*):设置指定行的表头
  • 核心信号
    • cellClicked(int row,int column):点击单元格时触发
    • cellDoubleClicked(int row,int column):双击单元格时触发
    • cellEntered(int row,int column):鼠标进入单元格时触发
    • currentCellChanged(int row,int column,int previousRow,int previousColumn):选中不同单元格时触发
  • 核心方法
    • row():获取当前是第几行
    • coumn():获取当前是第几列
    • setText(const QString&):设置文本
    • setTextAlignment(int):设置文本对齐
    • setIcon(const QIcon&):设置图标
    • setSelected(bool):设置被选中
    • setSizeHints(const QSize&):设置尺寸
    • setFront(const QFront&):设置字体

2.2.1 通过代码写入内容

cpp 复制代码
    // 创建行
    ui->tableWidget->insertRow(0);
    ui->tableWidget->insertRow(1);
    ui->tableWidget->insertRow(2);

    // 创建列
    ui->tableWidget->insertColumn(0);
    ui->tableWidget->insertColumn(1);
    ui->tableWidget->insertColumn(2);

    // 给3个列设定列名(设置水平方向的表头)
    ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("学号"));
    ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("姓名"));
    ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("年龄"));

    // 给表格中添加数据
    ui->tableWidget->setItem(0,0,new QTableWidgetItem("1001"));
    ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0,2,new QTableWidgetItem("20"));

    ui->tableWidget->setItem(1,0,new QTableWidgetItem("1002"));
    ui->tableWidget->setItem(1,1,new QTableWidgetItem("里斯"));
    ui->tableWidget->setItem(1,2,new QTableWidgetItem("19"));

    ui->tableWidget->setItem(2,0,new QTableWidgetItem("1003"));
    ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2,2,new QTableWidgetItem("22"));

2.2.2 添加删除行/列

cpp 复制代码
void Widget::on_pushButton_insertRow_clicked()
{
    // 需要先知道当前一共多少行
    int rowCount=ui->tableWidget->rowCount();
    // 在最后一行新增行,传的是下标
    ui->tableWidget->insertRow(rowCount);
}

void Widget::on_pushButton_deleteRow_clicked()
{
    // 获取到要删除的行号
    int curRow=ui->tableWidget->currentRow();
    // 删除这一行
    ui->tableWidget->removeRow(curRow);
}

void Widget::on_pushButton_InsertColumn_clicked()
{
    // 获取一共多少列
    int colCount=ui->tableWidget->columnCount();
    // 在对应的位置新增这一列
    ui->tableWidget->insertColumn(colCount);
    // 设置列名
    const QString& text=ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(colCount,new QTableWidgetItem(text));
}

void Widget::on_pushButton_deleteColumn_clicked()
{
    // 获取选中列
    int curCol=ui->tableWidget->currentColumn();
    // 删除这一列
    ui->tableWidget->removeColumn(curCol);
}

2.3 Tree Widget

  • 使用 QTreeWidget 表示一个树形控件,
  • 里面的每个元素都是一个 QTreeWidgetItem,每个 QTreeWidgetItem 可以包含多个文本和图标,每个文本/图标为一个列
  • 核心方法:
    • clear:清空所有子节点
    • addTopLevelItem(QTreeWidgetItem* item):新增顶层节点
      • 虽然是树形结构,但是没有体现出根节点,是从根节点的下一层子节点开始计算的
    • topLevelItem(int index):获取指定下标的顶层节点
    • indexOfTopLevelItem(QTreeWidgetItem* item):查询指定节点是顶层节点中的下标
    • takeTcopItem(int index):删除指定的顶层节点,返回 QTreeWidgetItem* 表示被删除的元素
    • currentItem():获取当前选中的节点,返回 QTreeWidgetItem*
    • setCurrentItem(QTreeWidgetItem* item):选中指定节点
    • setExpanded(bool):展开/关闭节点
    • setHeaderLabel(const QString& text):设置 TreeWidget 的 header 名称
  • 核心方法:
    • addChild(QTreeWidgetItem* child):新增子节点
    • childCount():子节点的个数
    • child(int index):获取指定下标的子节点,返回 QTreeWidgetItem*
    • takeChild(int index):删除对应下标的子节点
    • removeChild(QTreeWidgetItem* child):删除对应的子节点
    • parent():获取该元素的父节点

2.3.1 通过代码添加数据

cpp 复制代码
    // 设置根节点的名字
    ui->treeWidget->setHeaderLabel("动物");

    // 新增顶层节点
    QTreeWidgetItem* item1=new QTreeWidgetItem();
    // 每个节点都可以设置多个列,这里为了简单只设置一列
    item1->setText(0,"猫");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item1);

    // 新增顶层节点
    QTreeWidgetItem* item2=new QTreeWidgetItem();
    // 每个节点都可以设置多个列,这里为了简单只设置一列
    item2->setText(0,"狗");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item2);

    // 新增顶层节点
    QTreeWidgetItem* item3=new QTreeWidgetItem();
    // 每个节点都可以设置多个列,这里为了简单只设置一列
    item3->setText(0,"鸟");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item3);

    // 添加一些子节点
    QTreeWidgetItem* item4=new QTreeWidgetItem();
    item4->setText(0,"中华田园猫");
    item1->addChild(item4);

    QTreeWidgetItem* item5=new QTreeWidgetItem();
    item5->setText(0,"布偶猫");
    item1->addChild(item5);

    QTreeWidgetItem* item6=new QTreeWidgetItem();
    item6->setText(0,"暹罗猫");
    item1->addChild(item6);

2.3.2 添加到顶层元素、添加到选中元素子节点、删除选中元素

cpp 复制代码
void Widget::on_pushButton_insertTopLevelItem_clicked()
{
    // 获取到输入框的内容
    const QString& text=ui->lineEdit->text();
    // 构造一个QTreeWidgetItem
    QTreeWidgetItem* item =new QTreeWidgetItem();
    item->setText(0,text);
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item);
}

void Widget::on_pushButton_insertItem_clicked()
{
    // 获取到当前选中的节点
    QTreeWidgetItem* currentItem=ui->treeWidget->currentItem();
    if(currentItem==nullptr)
        return;
    // 获取到输入框的内容
    const QString& text=ui->lineEdit->text();
    // 构造一个QTreeWidgetItem
    QTreeWidgetItem* item =new QTreeWidgetItem();
    item->setText(0,text);
    currentItem->addChild(item);
}

void Widget::on_pushButton_deleteItem_clicked()
{
    // 获取到当前选中的节点
    QTreeWidgetItem* currentItem=ui->treeWidget->currentItem();
    if(currentItem==nullptr)
        return;
    // 删除选中的元素,需要先获取到父元素,通过父元素进行删除
    QTreeWidgetItem* parent=currentItem->parent();
    if(parent==nullptr)
    {
        // 顶层元素
        int index=ui->treeWidget->indexOfTopLevelItem(currentItem);
        ui->treeWidget->takeTopLevelItem(index);
    }else
    {
        // 普通元素
        parent->removeChild(currentItem);
    }
}

2.4 注意

  • 上述这几个控件相关的操作,数据都是在内存中保存的,无论在界面上做任何操作,重新运行程序,之前的数据就都没了
  • 如果想让数据能够重启也不丢失,就需要编写更多的代码把内存存储的数据获取到,写入到文件中,并且在下次运行的时候从文件加载数据
相关推荐
网创联盟,知识导航2 小时前
沐雨云香港直连500M大带宽云主机深度测评
经验分享·学习·测试工具
执笔画流年呀2 小时前
多线程及其特性
java·服务器·开发语言
良木生香2 小时前
【C++初阶】C++编程基石:编码表&&STL的入门指南
c语言·开发语言·数据结构·c++·算法
达帮主2 小时前
19.1 C语言链表 -- 简单
c语言·开发语言·链表
怎么没有名字注册了啊2 小时前
解决qt制作软件.app迁移问题(发布)Mac
开发语言·qt
llm大模型算法工程师weng2 小时前
Java高并发架构设计:从理论到实战的全链路解决方案
java·开发语言
gihigo19982 小时前
MATLAB地震面波数值模拟方案
开发语言·matlab
CeshirenTester2 小时前
Claude Code 不只是会写代码:这 10 个 Skills,才是效率分水岭
android·开发语言·kotlin
并不喜欢吃鱼2 小时前
从零开始C++----四.vector的使用与底层实现
开发语言·c++