Q:如何在Qt库的基础上,实现自定义控件呢? A:根据官方文档回答,就是继承需实现的控件,然后实现自定义功能。
以下是实现QListWidget控件的自定义item。 先看下最终效果是如何:
listItem
主界面UI操作流程:
主窗口中央控件是QListWidget,点击添加按钮,会随机向主窗口中央控件中添加自定义item;选中某条前的可选框,如果选中,点击右侧的删除图标,会弹出提示是否删除;如果不选中,右侧删除图标无法点击;点击是,删除当前item,点击否,不删除。 实现需解决问题1:如何在QListWidget中添加带有按钮、文本等其它控件的项?
2:选中某项后如何响应?QListWidget自带的item响应为什么不生效?
3:如何选中删除按钮后,通知QListWidget做出删除当前item的操作?
示例示例中用到的方法,多为控件的成员方法,如需了解更多,可选择某类按F1查阅帮助文档。 首先是主窗口代码 mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:// 项列表控件中添加Itemvoid on_btn_add_clicked();private:Ui::MainWindow *ui;};#endif // MAINWINDOW_Hmainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include <custemitem.h>#include <QMessageBox>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);}MainWindow::~MainWindow(){delete ui;}void MainWindow::on_btn_add_clicked(){// 创建itemQListWidgetItem* pItem = new QListWidgetItem("");ui->listWidget->addItem(pItem);// 创建自定义widgetcustemItem* pCustomItem = new custemItem(pItem);ui->listWidget->setItemWidget(pItem, pCustomItem);ui->listWidget->setCurrentItem(pItem);// 实现自定义信号和槽,当删除时,从列表中删除itemconnect(pCustomItem, &custemItem::emit_del, this, [&](QListWidgetItem* pItem){QMessageBox::StandardButton btn = QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("是否删除?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);if(QMessageBox::No == btn)return;ui->listWidget->removeItemWidget(pItem);delete pItem;pItem = nullptr;});}其次是自定义QWidget控件代码 customitem.h
#ifndef CUSTEMITEM_H#define CUSTEMITEM_H#include <QWidget>#include <QListWidgetItem>namespace Ui {class custemItem;}class custemItem : public QWidget{Q_OBJECTpublic:explicit custemItem(QListWidgetItem* pItem, QWidget *parent = nullptr);~custemItem();signals:void emit_del(QListWidgetItem* pItem);private slots:void on_pushButton_clicked();private:Ui::custemItem *ui;QListWidgetItem* m_pItem;};#endif // CUSTEMITEM_Hcustomitem.cpp
#include "custemitem.h"#include "ui_custemitem.h"#include "defind.h"custemItem::custemItem(QListWidgetItem* pItem, QWidget *parent) :QWidget(parent),ui(new Ui::custemItem),m_pItem(pItem){ui->setupUi(this);ui->pushButton->setEnabled(false);// 随机(伪随机)创建一些文本int nRand = qrand()%4;ui->checkBox->setText(slText.at(nRand));ui->checkBox->setIcon(QIcon(slIcon.at(nRand)));// 根据选择状态,来进行删除按钮功能使能connect(ui->checkBox, &QCheckBox::clicked, this, [=](){ui->pushButton->setEnabled(ui->checkBox->isChecked());});}custemItem::~custemItem(){delete ui;}void custemItem::on_pushButton_clicked(){if(ui->checkBox->isChecked()){emit emit_del(m_pItem);}else{}}增加一个随机显示图标和文本的类 defind.h
#ifndef DEFIND_H#define DEFIND_H#include <QStringList>#include <QList>#include <QIcon>// 随机添加一些文本,使示例看起来更加丰富QStringList slText = {"12312312.mp3", "dfdafds.mp4", "zcvzcvzxv.txt", "asdfasdfafsafdf.avi"};QList<QString> slIcon = {":/res/mp3.png", ":/res/mp4.png", ":/res/TXT.png", ":/res/Video.png"};#endif // DEFIND_H最后是main代码 main.cpp
#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]){QApplication a(argc, argv);MainWindow w;w.show();return a.exec();}如果疑问,可留言讨论。