目的
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_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
// 项列表控件中添加Item
void on_btn_add_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.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()
{
// 创建item
QListWidgetItem* pItem = new QListWidgetItem("");
ui->listWidget->addItem(pItem);
// 创建自定义widget
custemItem* pCustomItem = new custemItem(pItem);
ui->listWidget->setItemWidget(pItem, pCustomItem);
ui->listWidget->setCurrentItem(pItem);
// 实现自定义信号和槽,当删除时,从列表中删除item
connect(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_OBJECT
public:
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_H
customitem.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();
}
如果疑问,可留言讨论。