共计 9645 个字符,预计需要花费 25 分钟才能阅读完成。
导读 | 这篇文章主要为大家详细介绍了如何使用 Qt 制作一个 ListView,点击 ListView 的 Item 可以用于测试 OpenCV 的各种效果,感兴趣的小伙伴可以了解一下 |
1、概述
案例:使用 Qt 制作一个 ListView。点击 ListView 的 Item 可以用于测试 OpenCV 的各种效果
自定义一个:MainListView 继承 QListWidget、MainListViewItem 继承 QListWidgetItem
2、代码示例
1. 自定义 QListWidget
mainlistview.h
class MainListView : public QListWidget | |
{ | |
Q_OBJECT | |
public: | |
explicit MainListView(QWidget *parent = nullptr); | |
protected: | |
void mousePressEvent(QMouseEvent *event); | |
void mouseReleaseEvent(QMouseEvent *event); | |
void mouseMoveEvent(QMouseEvent *event); | |
void leaveEvent(QEvent *event); | |
private: | |
QPoint startPoint; | |
MainListViewItem *theHighlightItem = nullptr; | |
MainListViewItem *oldHighlightItem = nullptr; | |
MainListViewItem *theSelectedItem = nullptr; | |
MainListViewItem *oldSelectedItem = nullptr; | |
Chapter3Option * option = new Chapter3Option(); | |
signals: | |
public slots: | |
void updateSelectedIcon(); | |
void onMainItemClick(QListWidgetItem *item); | |
}; |
mainlistview.cpp
#include "mainlistview.h" | |
MainListView::MainListView(QWidget *parent) : QListWidget(parent) | |
{setMouseTracking(true); | |
// 连接信号与槽函数,如果选中项发生变化则触发 item 图标的更新. 都是当前对象发生 | |
connect(this,&MainListView::itemSelectionChanged,this,&MainListView::updateSelectedIcon); | |
connect(this,&MainListView::itemClicked,this,&MainListView::onMainItemClick); | |
} | |
/** | |
* 处理鼠标 hove 事件,item 图标就变成 hove 状态 | |
* @brief MainListView::mouseMoveEvent | |
* @param event | |
*/ | |
void MainListView::mouseMoveEvent(QMouseEvent *event){ | |
oldHighlightItem = theHighlightItem; | |
theHighlightItem = static_cast(itemAt(event->pos())); | |
// 旧的 hover 的 item 图标回复原状 (条件是该 item 没有被选中) | |
// 新的 hover 的 iten 图标变成 hover 状态 (条件是该 item 没有被选中) | |
if(oldHighlightItem != theHighlightItem){if(oldHighlightItem && !oldHighlightItem->isSelected()) oldHighlightItem->setIcon(oldHighlightItem->mIcon); | |
if(theHighlightItem && !theHighlightItem->isSelected()) theHighlightItem->setIcon(theHighlightItem->mIconHover); | |
} | |
} | |
/** | |
* 鼠标按下(这个可以当做 item 的点击事件,能够正常执行)* @brief MainListView::mousePressEvent | |
* @param event | |
*/ | |
void MainListView::mousePressEvent(QMouseEvent *event){if(event->buttons()&Qt::LeftButton){startPoint = event->pos(); | |
MainListViewItem *item = static_cast(itemAt(event->pos())); | |
QString filePath = QFileDialog::getOpenFileName(this, tr("选择视频"), "C:\\Users\\wei.yang\\Downloads\\opencv_res", tr("Image Files(*.jpg *.png)")); | |
const char *fileRealPath = filePath.toStdString().c_str();// 将 QString 转换为 char* | |
qDebug() text()"pos:"mPos; | |
switch (item->mPos) { | |
case 1:// 显示原图 | |
option->showSrcImage(fileRealPath); | |
break; | |
case 2:// 像素取反 | |
option->pixleReverse(fileRealPath); | |
break; | |
case 3:// 图像融合 | |
option->imageFuse("",""); | |
break; | |
case 4:// 调整图像亮度及对比度 | |
option->increaseBrightnessContrastRatio(fileRealPath); | |
break; | |
case 5:// 绘制线、矩形、椭圆、圆、多边形、文本 | |
option->drawShape(); | |
break; | |
case 6:// 均值模糊:用于图像的降噪 | |
option->showBlur(fileRealPath); | |
break; | |
case 7:// 高斯模糊:用于图像的降噪,其对自然界的噪声有很好的抑制作用 | |
option->showGaussianBlue(fileRealPath); | |
break; | |
case 8:// 中值滤波:终止滤波用于图像的降噪,其对椒盐噪声有很好的抑制作用(黑白点)option->showMediaBlur(fileRealPath); | |
break; | |
case 9:// 双边滤波:其可以很好的保留边缘的同时对平坦区域进行降噪 | |
option->showBilateralFilter(fileRealPath); | |
break; | |
case 10:// 提起图像中的英文字母 | |
option->showCleanImage(fileRealPath); | |
break; | |
case 11:// 形态学开操作 | |
option->showImageOpen(fileRealPath); | |
break; | |
case 12:// 形态学闭操作 | |
option->showImageClose(fileRealPath); | |
break; | |
case 13:// 形态学梯度(基本梯度):膨胀减去腐蚀 | |
option->showMorphologicalGradient(fileRealPath); | |
break; | |
case 14:// 顶帽操作:相当于原图像与开操作之间的差值图像 | |
option->showTopHat(fileRealPath); | |
break; | |
case 15:// 黑帽操作:相当于原图像与闭操作之间的差值图像 | |
option->showBlackHat(fileRealPath); | |
break; | |
case 16:// 小案例:提取提取项目中的字母或者直线 | |
option->showLines(fileRealPath,0); | |
break; | |
case 17:// 上采样: 利用拉普拉斯金字塔进行图像重建 | |
option->showPyrUp(fileRealPath); | |
break; | |
case 18:// 降采样:利用高斯金字塔进行降采样 | |
option->showPyrDown(fileRealPath); | |
break; | |
case 19:// 高斯不同:把同一张图片再不同的参数下做高斯模糊之后的结果相减,得到的输出图像称为高斯不同 | |
option->showGaussianDiff(fileRealPath); | |
break; | |
case 20:// 使用自定义卷积核 filter2D | |
option->showCustomKernelFilter2D(fileRealPath,1); | |
break; | |
case 21://1. 合并 rebort 和 sobel 的 x 方向梯度和 y 方向的梯度 | |
option->showCustomKernelFilter2DMergeXY(fileRealPath); | |
break; | |
case 22:// 填充图像边缘 | |
option->showCopyMakeBorder(fileRealPath); | |
break; | |
case 23:// 使用 Sobel 和 Scharr 计算图形梯度 | |
option->showSobelAndScharr(fileRealPath); | |
break; | |
case 24:// 使用拉普拉斯算子显示梯度图像 | |
option->showLaplacian(fileRealPath); | |
break; | |
case 25:// 边缘检测 | |
option->showCanny(fileRealPath); | |
break; | |
} | |
} | |
} | |
/** | |
* 释放鼠标 | |
* @brief MainListView::mouseReleaseEvent | |
* @param event | |
*/ | |
void MainListView::mouseReleaseEvent(QMouseEvent *event){ | |
// 如果鼠标释放位置和单击位置相距超过 5 像素,则不会触发 item 选中 | |
if((event->pos() - startPoint).manhattanLength() > 5) return; | |
MainListViewItem *item = static_cast(itemAt(event->pos())); | |
setCurrentItem(item); | |
} | |
/** | |
* 处理鼠标离开后,hover 图标回复正常状态 | |
* @brief MainListView::leaveEvent | |
* @param event | |
*/ | |
void MainListView::leaveEvent(QEvent *event){Q_UNUSED(event); | |
oldHighlightItem = theHighlightItem; | |
if(oldHighlightItem && !oldHighlightItem->isSelected()) oldHighlightItem->setIcon(oldHighlightItem->mIcon); | |
oldHighlightItem = theHighlightItem = nullptr; | |
} | |
void MainListView::updateSelectedIcon(){ | |
oldSelectedItem = theSelectedItem; | |
theSelectedItem = static_cast(currentItem()); | |
// 之前被选中的 item 图标回复原样 | |
// 新被选中的 item 图标变成 hover 状态 | |
if(oldSelectedItem != theSelectedItem){if(oldSelectedItem) oldSelectedItem->setIcon(oldSelectedItem->mIcon); | |
if(theSelectedItem) theSelectedItem->setIcon(theSelectedItem->mIconHover); | |
} | |
} | |
// 这个槽函数并没有执行 | |
void MainListView::onMainItemClick(QListWidgetItem *item){qDebug() |
2. 自定义 QListWidgetItem
mainlistviewitem.h
class MainListViewItem : public QListWidgetItem | |
{ | |
//Q_OBJECT // 由于 QListWidgetItem 没有 QObject 属性,所以 Q_OBJECT 需要注释掉 | |
public: | |
explicit MainListViewItem(QString itemTitle,const QIcon &icon, const QIcon &iconHover,int pos,QListWidget *parent = nullptr); | |
/** | |
* 设置 item 的图标 | |
* @brief setItemIcon | |
* @param icon | |
* @param iconHover | |
*/ | |
// void setItemIcon(const QIcon &icon,const QIcon &iconHover); | |
public: | |
QIcon mIcon;// 默认图标 | |
QIcon mIconHover;// 选中时图标 | |
int mPos;// 第一个编辑 | |
signals: | |
}; |
mainlistviewitem.cpp
/** | |
* 自定义主页 ListView 的 Item 项 | |
* @brief MainListViewItem::MainListViewItem | |
* @param parent | |
*/ | |
MainListViewItem::MainListViewItem(QString itemTitle,const QIcon &icon, const QIcon &iconHover,int pos,QListWidget *parent) : QListWidgetItem(parent) | |
{setText(itemTitle); | |
mIcon = icon; | |
mIconHover = iconHover; | |
setIcon(mIcon); | |
setSizeHint(QSize(360,47)); | |
mPos = pos; | |
} |
3. 使用
void MainWindow::createListView(QWidget *parent){listView = new MainListView(this); | |
listView->setFocusPolicy(Qt::NoFocus); // 这样可禁用 tab 键和上下方向键并且除去复选框 | |
listView->setFixedHeight(320); | |
listView->setFont(QFont("宋体", 14, QFont::DemiBold)); | |
listView->setFixedSize(QSize(360,480)); | |
listView->move(0,menuBar()->height()); | |
listView->setStyleSheet("{outline:0px;}" // 除去复选框 | |
"MainListViewItem{background:rgb(245, 245, 247); border:0px; margin:0px 0px 0px 0px;}" | |
"MainListViewItem::Item{height:40px; border:0px; padding-left:14px; color:rgba(200, 40, 40, 255);}" | |
"MainListViewItem::Item:hover{color:rgba(40, 40, 200, 255);}" | |
"MainListViewItem::Item:selected{background:rgb(230, 231, 234); color:rgba(40, 40, 200, 255); border-left:4px solid rgb(180, 0, 0);}" | |
"QListWidget::Item:selected:active{background:rgb(230, 231, 234); color:rgba(40, 40, 200, 255); border-left:4px solid rgb(180, 0, 0);}"); | |
new MainListViewItem("显示原图",QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),1,listView); | |
new MainListViewItem(tr("像素取反"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),2,listView); | |
new MainListViewItem(tr("图像融合"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),3,listView); | |
new MainListViewItem(tr("调整图像亮度及对比度"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),4,listView); | |
new MainListViewItem(tr("绘制线、矩形、椭圆、圆、多边形、文本"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),5,listView); | |
new MainListViewItem(tr("均值模糊"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),6,listView); | |
new MainListViewItem(tr("高斯模糊"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),7,listView); | |
new MainListViewItem(tr("中值滤波"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),8,listView); | |
new MainListViewItem(tr("双边滤波"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),9,listView); | |
new MainListViewItem(tr("提取图像中的英文字母"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),10,listView); | |
new MainListViewItem(tr("形态学开操作"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),11,listView); | |
new MainListViewItem(tr("形态学闭操作"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),12,listView); | |
new MainListViewItem(tr("形态学梯度(基本梯度)"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),13,listView); | |
new MainListViewItem(tr("顶帽操作"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),14,listView); | |
new MainListViewItem(tr("黑帽操作"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),15,listView); | |
new MainListViewItem(tr("小案例:提取提取项目中的字母或者直线"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),16,listView); | |
new MainListViewItem(tr("上采样"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),17,listView); | |
new MainListViewItem(tr("降采样"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),18,listView); | |
new MainListViewItem(tr("高斯不同"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),19,listView); | |
new MainListViewItem(tr("使用自定义卷积核 filter2D"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),20,listView); | |
new MainListViewItem(tr("合并 rebort 及 Sobel 的 x 方向梯度和 y 方向的梯度"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),21,listView); | |
new MainListViewItem(tr("填充图像边缘"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),22,listView); | |
new MainListViewItem(tr("使用 Sobel 和 Scharr 计算图形梯度"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),23,listView); | |
new MainListViewItem(tr("使用拉普拉斯算子显示梯度图像"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),24,listView); | |
new MainListViewItem(tr("边缘检测"),QIcon(":res/icon_main_list.png"),QIcon(":res/icon_main_list.png"),25,listView); | |
// connect(listView,&MainListView::itemClicked,listView,&MainListView::onMainItemClick); | |
} | |
// 最后一步:创建 ListView,然后运行就行了 | |
createListView(this); |
3、图片演示
到此这篇关于 QT 实现制作一个 ListView 列表的示例代码的文章就介绍到这了
正文完
星哥玩云-微信公众号
