QT——使用QListWidget、QListWidgetItem、QWidget实现自定义管理列表

作者:小 琛
欢迎转载,请标明出处

文章目录

    • 需求场景
    • 思路描述
    • Qt模块
      • QListWidget
      • QListWidgetItem
      • 自定义QWidget配合QListWidget
    • 例子:实现一个json文件管理窗口

需求场景

因工作需要,开发一个文件管理窗口,要让使用者可以对若干文件进行一系列操作。本文着重讲述ui实现,如何作出一个漂亮的列表

思路描述

这里仅描述思路,如果你对Qt并不熟悉,大致了解一下即可,后文会描述具体用法

  1. 利用Qt提供的类:QListWidget、QListWidgetItem,其中QListWidget为列表类,QListWidgetItem可以理解为每一项的数据类
  2. 原生的QListWidget一定不能满足我们的需求,因此我们构建一个类继承自QListWidget,在子类中重新定义ui风格
  3. 在2中,我们做到了自定义列表,但列表内的具体每一项内容仍然是原生的,因此我们可以自定义一个QWidget,这个widget可以根据我们具体的场景绘制,在插入的时候,使用我们的自定义QWidget作为每一项内容
  4. QListWidgetItem是列表插入必不可少的,并且我们制作列表时,一定会用到一些数据,也可以用它来存储
    在这里插入图片描述

Qt模块

QListWidget

QListWidget是一个列表控件,可以显示一个可滚动的列表,列表项可以是纯文本、图标或者自定义控件。QListWidget使用QListWidgetItem来表示列表项,每个QListWidgetItem可以设置列表项的文本、图标和状态。

下面是一些QListWidget的常见用法:

  1. 添加列表项

可以使用addItem()方法添加一个列表项,可以设置列表项的文本和图标:

QListWidget *listWidget = new QListWidget(this);// 添加纯文本列表项
listWidget->addItem("Item 1");// 添加带图标的列表项
QListWidgetItem *item2 = new QListWidgetItem(QIcon(":/images/icon.png"), "Item 2");
listWidget->addItem(item2);// 添加自定义控件
QLabel *label = new QLabel("Item 3");
QListWidgetItem *item3 = new QListWidgetItem();
listWidget->addItem(item3);
listWidget->setItemWidget(item3, label);
  1. 获取当前选中的列表项

可以使用currentItem()方法获取当前选中的列表项:

QListWidgetItem *item = listWidget->currentItem();
if (item) {qDebug() << "Selected item: " << item->text();
}
  1. 设置列表项的状态

可以使用setCheckState()方法设置列表项的状态,使得列表项可以被选中或未选中:

QListWidgetItem *item = new QListWidgetItem("Item 1");
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // 开启用户可选中的标志
item->setCheckState(Qt::Unchecked); // 初始为未选中状态listWidget->addItem(item);
  1. 删除列表项

可以使用takeItem()方法删除一个列表项:

QListWidgetItem *item = listWidget->currentItem();
if (item) {listWidget->takeItem(listWidget->row(item)); // 删除当前选中的列表项
}

QListWidgetItem

QListWidgetItem是QListWidget中的列表项,每个QListWidget中的列表项都是一个QListWidgetItem对象。QListWidgetItem包含了列表项的文本、图标、状态等信息,可以通过QListWidgetItem的方法来设置和获取这些信息。

下面是一些常见的QListWidgetItem的用法:

  1. 设置列表项的文本和图标

可以使用setText()方法和setIcon()方法设置列表项的文本和图标:

QListWidgetItem *item = new QListWidgetItem();
item->setText("Item 1");
item->setIcon(QIcon(":/images/icon.png"));
listWidget->addItem(item);
  1. 获取列表项的文本和图标

可以使用text()方法和icon()方法获取列表项的文本和图标:

QListWidgetItem *item = listWidget->currentItem();
if (item) {QString text = item->text();QIcon icon = item->icon();
}
  1. 设置列表项的状态

可以使用setCheckState()方法设置列表项的状态,使得列表项可以被选中或未选中:

QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // 开启用户可选中的标志
item->setCheckState(Qt::Unchecked); // 初始为未选中状态
listWidget->addItem(item);
  1. 获取列表项的状态

可以使用checkState()方法获取列表项的状态,返回值为Qt::CheckState枚举类型,表示列表项的选中状态:

QListWidgetItem *item = listWidget->currentItem();
if (item) {Qt::CheckState state = item->checkState();
}
  1. 自定义列表项

可以使用QListWidgetItem的方法setItemWidget()方法设置自定义控件作为列表项:

QLabel *label = new QLabel("Custom Item");
QListWidgetItem *item = new QListWidgetItem();
listWidget->addItem(item);
listWidget->setItemWidget(item, label);

自定义QWidget配合QListWidget

在使用QListWidget时,有时需要自定义列表项的内容,此时可以使用QWidget作为列表项的内容。QWidget可以是任何自定义控件,例如QPushButton、QLabel等。也就是说,你可以自定义一个任意构建的widget,将其作为列表的每一项内容。

例子:实现一个json文件管理窗口

文件构造:
JsonListWidget.h+JsonListWidget.cpp
JsonListWidgetItem.h+JsonListWidgetItem.cpp
JsonItemWidget.h+JsonItemWidget.cpp

注意的点:

  1. 下面的例子,并不能直接运行,因为包含了很多我自定义的控件,仅限于了解整个结构
  2. 整个设计:JsonItemWidget是我的自定义widget,里面包含了我定义每一项的具体内容,其中的控件被触发时绑定信号,JsonItemWidget再绑定widget中的信号,实现事件的抛;JsonListWidget是列表项,修改了很多属性来实现我想要的ui效果;JsonListWidgetItem是自定义的Item,其中预留了operate >,该接口可以完成自定义排序功能;插入的时候,调用setItemWidget接口完成

JsonListWidget.h

#pragma once#include <QListWidget>
#include "JsonItemDataDef.h"class JsonListItem;
class QListWidgetItem;
class JsonListWidget : public QListWidget {Q_OBJECT
public:explicit JsonListWidget(QWidget* parent);~JsonListWidget();void addJson(const JsonItemData& JsonData);void addJsonWithFlicker(const JsonItemData& JsonData);void updateJsonName(const QString& oldName, const QString& newName);void updateJsonInfo(const QString& name, const JsonItemData& data);void deleteJsonWithName(const QString& name);bool haveJsonByName(const QString& name);private:QListWidgetItem* findWidgetItemByName(const QString& name);signals:void sigOpenJsonFileFolder();void sigJsonRun(const QString& name);void sigItemNameChanged(const QString& oldName, const QString& newName);void sigItemDelete(const QString& name);void sigItemSetting(const QString& name);protected:virtual bool eventFilter(QObject* object, QEvent* event) override;};

JsonListWidget.cpp

#include "JsonListWidget.h"
#include "JsonListItem.h"
#include "NemuColor.h"
#include "AppUtil.h"
#include <QPainter>
#include <QDateTime>
#include <QEvent>
#include <QTimer>enum ItemRole {kRoleIndex = Qt::UserRole + 1,kRoleName,kRoleDate,kRoleTime,kRoleScreen,
};JsonListWidget::JsonListWidget(QWidget *parent) : QListWidget(parent) {setFrameShape(QFrame::NoFrame);setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);viewport()->setContentsMargins(0, 0, 0, 0);setStyleSheet(QString("QListWidget{background-color:%1;border: 1px solid %2; border-bottom-left-radius: %3px; ""border-bottom-right-radius: %4px; outline:0px;}""QListWidget::item:hover{background-color:%5;}""QListWidget::item:selected{border:none;}""QScrollBar:vertical{width:4px; background:transparent; padding:0px; border:0px;}""QScrollBar::handle:vertical:hover,QScrollBar::handle:vertical:pressed{background:%7;}""QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{background:transparent;border:0px;}""QScrollBar::add-line:vertical,QScrollBar::sub-line:vertical{background:transparent;border:0px;}").arg(NemuUiLib::NemuColor::getGrey8().name(QColor::HexArgb)).arg(AppUtil::isWin11() ? "#44464b" : "#192027").arg(AppUtil::isWin11() ? 8 : 0).arg(AppUtil::isWin11() ? 8 : 0).arg(NemuUiLib::NemuColor::getFill1().name(QColor::HexArgb)).arg(NemuUiLib::NemuColor::getFill2().name(QColor::HexArgb)).arg(NemuUiLib::NemuColor::getGrey3().name(QColor::HexArgb)));if (auto widget = findChild<QWidget *>("qt_scrollarea_vcontainer")) {widget->installEventFilter(this);}setViewMode(ListMode);
}JsonListWidget::~JsonListWidget() {}void JsonListWidget::addJson(const JsonItemData &JsonData) {if (haveJsonByName(JsonData.name_)) {return;}JsonListItem *item = new JsonListItem(this);connect(item, &JsonListItem::sigItemOpenJsonFileFolder, this, &JsonListWidget::sigOpenJsonFileFolder);connect(item, &JsonListItem::sigItemJsonRun, this, &JsonListWidget::sigJsonRun);connect(item, &JsonListItem::sigNameChanged, this, &JsonListWidget::sigItemNameChanged);connect(item, &JsonListItem::sigDeleteButtonClicked, this, &JsonListWidget::sigItemDelete);connect(item, &JsonListItem::sigSettingButtonClicked, this, &JsonListWidget::sigItemSetting);item->setJsonName(JsonData.name_);item->setJsonTime(JsonData.time_);item->setJsonDate(JsonData.date_);item->setJsonScreen(JsonData.screen_);auto listItem = new QListWidgetItem(this);listItem->setData(kRoleIndex, JsonData.index_);listItem->setData(kRoleName, JsonData.name_);listItem->setData(kRoleScreen, JsonData.screen_);listItem->setData(kRoleTime, JsonData.time_);listItem->setData(kRoleDate, JsonData.date_);listItem->setSizeHint(item->size());insertItem(0, listItem);setItemWidget(listItem, item);
}void JsonListWidget::addJsonWithFlicker(const JsonItemData &JsonData) {if (haveJsonByName(JsonData.name_)) {return;}JsonListItem *item = new JsonListItem(this);connect(item, &JsonListItem::sigItemOpenJsonFileFolder, this, &JsonListWidget::sigOpenJsonFileFolder);connect(item, &JsonListItem::sigItemJsonRun, this, &JsonListWidget::sigJsonRun);connect(item, &JsonListItem::sigNameChanged, this, &JsonListWidget::sigItemNameChanged);connect(item, &JsonListItem::sigDeleteButtonClicked, this, &JsonListWidget::sigItemDelete);connect(item, &JsonListItem::sigSettingButtonClicked, this, &JsonListWidget::sigItemSetting);item->setJsonName(JsonData.name_);item->setJsonTime(JsonData.time_);item->setJsonDate(JsonData.date_);item->setJsonScreen(JsonData.screen_);auto listItem = new QListWidgetItem();listItem->setData(kRoleIndex, JsonData.index_);listItem->setData(kRoleName, JsonData.name_);listItem->setData(kRoleScreen, JsonData.screen_);listItem->setData(kRoleTime, JsonData.time_);listItem->setData(kRoleDate, JsonData.date_);listItem->setSizeHint(item->size());insertItem(0, listItem);setItemWidget(listItem, item);update();listItem->setBackgroundColor(NemuUiLib::NemuColor::getFill1());QTimer::singleShot(1000, [listItem]() { listItem->setBackgroundColor(NemuUiLib::NemuColor::getGrey8()); });
}bool JsonListWidget::haveJsonByName(const QString& name) {bool ret = false;for (int row = 0; row < count(); ++row) {auto widgetItem = item(row);if (!widgetItem) {continue;}if (name != widgetItem->data(kRoleName).toString()) {continue;}ret = true;break;}return ret;
}void JsonListWidget::deleteJsonWithName(const QString& name) {int listCount = count();for (int row = 0; row < listCount; ++row) {auto widgetItem = item(row);if (!widgetItem) {continue;}if (name != widgetItem->data(kRoleName).toString()) {continue;}takeItem(row);break;}
}void JsonListWidget::updateJsonName(const QString &oldName, const QString &newName) {if (auto widgeItem = findWidgetItemByName(oldName)) {widgeItem->setData(kRoleName, newName);if (auto widget = qobject_cast<JsonListItem *>(itemWidget(widgeItem))) {widget->setJsonName(newName);}}
}void JsonListWidget::updateJsonInfo(const QString &name, const JsonItemData &data) {if (auto widgeItem = findWidgetItemByName(name)) {widgeItem->setData(kRoleIndex, data.index_);widgeItem->setData(kRoleName, name);widgeItem->setData(kRoleDate, data.date_);widgeItem->setData(kRoleTime, data.time_);widgeItem->setData(kRoleTime, data.screen_);if (auto widget = qobject_cast<JsonListItem *>(itemWidget(widgeItem))) {widget->setIndex(data.index_);widget->setJsonName(name);widget->setJsonDate(data.date_);widget->setJsonTime(data.time_);widget->setJsonScreen(data.screen_);}}
}QListWidgetItem *JsonListWidget::findWidgetItemByName(const QString &name) {int listCount = count();for (int row = 0; row < listCount; ++row) {auto widgetItem = item(row);if (!widgetItem) {continue;}if (name != widgetItem->data(kRoleName).toString()) {continue;}return widgetItem;}return nullptr;
}bool JsonListWidget::eventFilter(QObject *object, QEvent *event) {// scrollbar设置位置的时机比较多,无法全面覆盖,只能在产生move事件之后再进行调整auto widget = findChild<QWidget *>("qt_scrollarea_vcontainer");if (widget && widget == object && event->type() == QEvent::Move) {QPoint pos = widget->pos();if (pos.x() && (pos.x() == rect().width() - widget->width())) {QRect rc1 = widget->geometry();pos -= QPoint(4, 0);widget->move(pos);}}return QListWidget::eventFilter(object, event);
}

JsonItemWidget.h

#pragma once#include <QWidget>
#include "JsonItemDataDef.h"class QStackedWidget;
class QStackedLayout;
class QLabel;
class QLineEdit;
class QVBoxLayout;
class QPushButton;
class RecorderPushButton18;
class RecorderTextLabel;
class JsonListItem : public QWidget {Q_OBJECT
public:explicit JsonListItem(QWidget* parent);~JsonListItem();void setIndex(const QString& index);void setScriptName(const QString& name);void setScriptDate(const QString& date);void setScriptTime(const QString& time);void setScriptScreen(const QString& screen);void setModifyTime(quint64 time);signals:void sigCheckStateChanged(const QString& index, Qt::CheckState state);void sigItemOpenScriptFileFolder();void sigItemScriptRun(const QString& name);void sigNameChanged(const QString& oldName, const QString& newName);void sigDeleteButtonClicked(const QString& name);void sigSettingButtonClicked(const QString& name);protected:virtual void enterEvent(QEvent* event) override;virtual void leaveEvent(QEvent* event) override;virtual void focusOutEvent(QFocusEvent* event) override;bool eventFilter(QObject* object, QEvent* event) override;private:QWidget* initLeftInfoWidget();QWidget* initRightButtonWidget();void ensureRenameEdit();void elidedName(NemuUiLib::NemuRichText1* label, const QString& name);void showNameLabel();void showRenameEdit();private:QString index_;QString name_;QString time_;QString screen_;QLable* nameLabel_;QLable* dateLabel_;QLabel* timeLabel_;QLbale* screenLabel_;QLineEdit* renameEdit_;QPushButton* openFolderButton_;QPushButton* settingButton_;QPushButton* deleteButton_;QVBoxLayout* centerLayout_;bool mouseEntered_;QPushButton* operatorButton_;};

JsonItemWidget.cpp

#include "JsonListItem.h"
#include "../../common/RecorderPushButton.h"
#include "../../common/RecorderTextLabel.h"
#include "nemu-ui-lib/control/NemuImage.h"
#include "nemu-ui-lib/control/NemuRichText.h"
#include "nemu-ui-lib/control/NemuCheckBox.h"
#include "nemu-ui-lib/control/NemuLine.h"
#include "nemu-ui-lib/control/NemuLineEdit.h"
#include "nemu-ui-lib/font/NemuFont.h"
#include "nemu-ui-lib/color/NemuColor.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QStackedWidget>
#include <QStackedLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QValidator>
#include <QRegularExpression>JsonListItem::JsonListItem(QWidget* parent): QWidget(parent),nameLabel_(nullptr),renameEdit_(nullptr),openFolderButton_(nullptr),settingButton_(nullptr),deleteButton_(nullptr),operatorButton_(nullptr),mouseEntered_(false) {setFixedSize(800, 80);centerLayout_ = new QVBoxLayout(this);centerLayout_->setAlignment(Qt::AlignCenter);centerLayout_->setSpacing(0);centerLayout_->setContentsMargins(0, 0, 0, 0);auto mainLayout = new QHBoxLayout();mainLayout->setContentsMargins(40, 18, 40, 16);mainLayout->setAlignment(Qt::AlignCenter);mainLayout->setSpacing(0);installEventFilter(this);mainLayout->addWidget(initLeftInfoWidget());mainLayout->addWidget(initRightButtonWidget(), 0, Qt::AlignVCenter);const auto line = new Line2({720, 1}, {40, 0, 40, 0}, this); //centerLayout_->addStretch();centerLayout_->addLayout(mainLayout);//centerLayout_->addStretch();centerLayout_->addWidget(line, 0, Qt::AlignBottom);adjustSize();
}JsonListItem::~JsonListItem() {if (renameEdit_) {renameEdit_->removeEventFilter(this);}removeEventFilter(this);
}QWidget* JsonListItem::initLeftInfoWidget() {auto widget = new QWidget(this);auto centerLayout = new QVBoxLayout(widget);centerLayout->setAlignment(Qt::AlignTop);centerLayout->setSpacing(0);centerLayout->setContentsMargins(0, 0, 0, 0);nameLabel_ = new NemuUiLib::NemuRichText1(300, getFont14(), QString(), widget);//nameLabel_->installEventFilter(this);nameLabel_->setFixedHeight(24);nameLabel_->document()->setDocumentMargin(0);nameLabel_->setStyleSheet(QString("QTextBrowser{color: %1; border: none; background-color: transparent}").arg(getWhite1().name(QColor::HexArgb)));centerLayout->addWidget(nameLabel_, 0, Qt::AlignTop | Qt::AlignLeft);QSpacerItem* spacer = new QSpacerItem(0, 4, QSizePolicy::Expanding, QSizePolicy::Fixed);centerLayout->addItem(spacer);auto dateAndScrenLayout = new QHBoxLayout();dateAndScrenLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);dateAndScrenLayout->setSpacing(0);dateAndScrenLayout->setContentsMargins(0, 0, 0, 0);auto dataImage = new Image1(QSize(16, 16), ":/resources/images/ic_calendar.svg", widget);dateAndScrenLayout->addWidget(dataImage);dateAndScrenLayout->addSpacing(2);dateLabel_ = new RichText2(QString(), getFont12(), widget);dateAndScrenLayout->addWidget(dateLabel_);dateAndScrenLayout->addSpacing(4);timeLabel_ = new Text2(QString(), getFont12(), widget);dateAndScrenLayout->addWidget(timeLabel_);dateAndScrenLayout->addSpacing(16);auto screenImage = new NemuImage1(QSize(16, 16), ":/resources/images/ic_resolution.svg", widget);dateAndScrenLayout->addWidget(screenImage);dateAndScrenLayout->addSpacing(2);screenLabel_ = new RichText2(QString(), getFont12(), widget);screenLabel_->setFixedWidth(55);dateAndScrenLayout->addWidget(screenLabel_);centerLayout->addLayout(dateAndScrenLayout);return widget;
}QWidget* JsonListItem::initRightButtonWidget() {auto operatorWidget = new QWidget(this);auto operatorLayout = new QHBoxLayout(operatorWidget);operatorLayout->setContentsMargins(6, 0, 0, 0);operatorLayout->setSpacing(20);openFolderButton_ = new QPushButton(this);openFolderButton_->setFixedSize(16, 16);openFolderButton_->setToolTip(tr("File location"));openFolderButton_->setStyleSheet(QString("QPushButton{border-image: url(:/resources/images/ic_folder location_normal.svg);}\QPushButton:hover{border-image: url(:/resources/images/ic_folder location_hover.svg);}\QPushButton:pressed{border-image: url(:/resources/images/ic_folder location_press.svg);}\QPushButton:disabled{border-image: url(:/resources/images/ic_folder location_disable.svg);}""QToolTip {""color: %1;""background-color: %2;""qproperty-shadow: none;""border: 0px solid #2A82DA;""}").arg(getWhite1().name(QColor::HexArgb)).arg(getGrey10().name(QColor::HexArgb)));connect(openFolderButton_, &QPushButton::clicked, this, [this]() { emit sigItemOpenJsonFileFolder(); });operatorLayout->addWidget(openFolderButton_);settingButton_ = new QPushButton(this);settingButton_->setFixedSize(16, 16);settingButton_->setToolTip(tr("execution setting"));settingButton_->setStyleSheet(QString("QPushButton{border-image: url(:/resources/images/ic_setting_normal.svg);}\QPushButton:hover{border-image: url(:/resources/images/ic_setting_hover.svg);}\QPushButton:pressed{border-image: url(:/resources/images/ic_setting_pressed.svg);}\QPushButton:disabled{border-image: url(:/resources/images/ic_setting_disabled.svg);}""QToolTip {""qproperty-shadow: none;""color: %1;""background-color: %2;""border: 0px solid #2A82DA;""}").arg(getWhite1().name(QColor::HexArgb)).arg(getGrey10().name(QColor::HexArgb)));connect(settingButton_, &QPushButton::clicked, this, [this]() { emit sigSettingButtonClicked(name_); });operatorLayout->addWidget(settingButton_);deleteButton_ = new QPushButton(this);deleteButton_->setFixedSize(16, 16);deleteButton_->setToolTip(tr("delete"));deleteButton_->setStyleSheet(QString("QPushButton{border-image: url(:/resources/images/ic_delete_normal.svg);}\QPushButton:hover{border-image: url(:/resources/images/ic_delete_hover.svg);}\QPushButton:pressed{border-image: url(:/resources/images/ic_delete_pressed.svg);}\QPushButton:disabled{border-image: url(:/resources/images/ic_delete_disabled.svg);}""QToolTip {""color: %1;""background-color: %2;""qproperty-shadow: none;""border: 0px solid #2A82DA;""}").arg(getWhite1().name(QColor::HexArgb)).arg(getGrey10().name(QColor::HexArgb)));connect(deleteButton_, &QPushButton::clicked, this, [this]() { emit sigDeleteButtonClicked(name_); });operatorLayout->addWidget(deleteButton_);operatorButton_ = new RecorderPushButton18(this);operatorButton_->setFixedSize(48, 24);operatorButton_->setIcon(QIcon(":/resources/images//ic_start_up.svg"));operatorButton_->setStateColor(NemuUiLib::NemuColor::getBrand1(), getBrand2(),NemuUiLib::NemuColor::getBrand1());operatorButton_->setToolTip(tr("execute"));operatorButton_->setStyleSheet(QString("QToolTip {""color: %1;""background-color: %2;""border: 0px solid #2A82DA;""}").arg(getWhite1().name(QColor::HexArgb)).arg(getGrey10().name(QColor::HexArgb)));operatorButton_->setVisible(true);connect(operatorButton_, &QPushButton::clicked, this, [this]() { sigItemJsonRun(name_);});operatorLayout->addWidget(operatorButton_);return operatorWidget;
}void JsonListItem::setIndex(const QString& index) { index_ = index; }void JsonListItem::setJsonName(const QString& name) {name_ = name;if (renameEdit_ && renameEdit_->isVisible()) {return;}elidedName(nameLabel_, name);
}void JsonListItem::setJsonDate(const QString& date) { time_ = date; const auto dateHtmlText = QString("<p align=\"left\" style=\"color: %1;\">%2</p>").arg(getGrey2().name(QColor::HexArgb)).arg(date);dateLabel_->updateText(dateHtmlText);dateLabel_->setFixedWidth(dateLabel_->adaptiveWidth(date, getFont12()));
}void JsonListItem::setJsonTime(const QString& time) {time_ = time;const auto dateHtmlText = QString("<p align=\"left\" style=\"color: %1;\">%2</p>").arg(NemuUiLib::NemuColor::getGrey2().name(QColor::HexArgb)).arg(time);timeLabel_->updateText(dateHtmlText);timeLabel_->setFixedWidth(timeLabel_->adaptiveWidth(time, getFont12()));
}void JsonListItem::setJsonScreen(const QString& screen) {screen_ = screen; const auto screenHtmlText = QString("<p align=\"left\" style=\"color: %1;\">%2</p>").arg(getGrey2().name(QColor::HexArgb)).arg(screen_);screenLabel_->updateText(screenHtmlText);screenLabel_->setFixedWidth(timeLabel_->adaptiveWidth(screen, getFont12()));
}void JsonListItem::setModifyTime(quint64 time) {}void JsonListItem::enterEvent(QEvent* event) {QWidget::enterEvent(event);
}void JsonListItem::leaveEvent(QEvent* event) {if (renameEdit_ && renameEdit_->isVisible()) {if (!renameEdit_->hasFocus()) {renameEdit_->setVisible(false);elidedName(nameLabel_, name_);}}QWidget::leaveEvent(event);
}void JsonListItem::focusOutEvent(QFocusEvent* event) {if (renameEdit_) {renameEdit_->setVisible(false);}QWidget::focusOutEvent(event);
}void JsonListItem::showNameLabel() {renameEdit_->setVisible(false);elidedName(nameLabel_, name_);
}void JsonListItem::showRenameEdit() {nameLabel_->clear();auto pos = nameLabel_->geometry();ensureRenameEdit();QSize sz = renameEdit_->size();renameEdit_->setGeometry(pos.x() + 40, pos.y() + 18, sz.width(), sz.height());renameEdit_->setText(name_);renameEdit_->setVisible(true);
}bool JsonListItem::eventFilter(QObject* object, QEvent* event) {if (object == renameEdit_) {if (event->type() == QEvent::FocusOut && !mouseEntered_) {showNameLabel();}} else if (object == this) {if (event->type() == QEvent::Enter) {mouseEntered_ = true;if (renameEdit_ && renameEdit_->isVisible()) {if (!renameEdit_->hasFocus()) {showNameLabel();}} else {showRenameEdit();}} else if (event->type() == QEvent::Leave) {mouseEntered_ = false;if (renameEdit_ && !renameEdit_->hasFocus()) {showNameLabel();}}} else if (object != renameEdit_) {if (renameEdit_ && !renameEdit_->hasFocus()) {showNameLabel();}}return QWidget::eventFilter(object, event);
}void JsonListItem::ensureRenameEdit() {if (renameEdit_) {return;}renameEdit_ = new QLineEdit(this);renameEdit_->setContextMenuPolicy(Qt::NoContextMenu);renameEdit_->setMaxLength(40);renameEdit_->setValidator(new QRegularExpressionValidator(QRegularExpression("^((?!\\\\|\\/|:|\\*|\\?|\"|<|>|\\|).)*$"), this));renameEdit_->setFixedSize(300, 24);renameEdit_->setFont(NemuUiLib::NemuFont::getFont12());renameEdit_->installEventFilter(this);renameEdit_->setStyleSheet(QString("QLineEdit{border-width:1px; border-style:solid; border-color:%1; padding-left:8px; padding-right:8px;""background-color: %1; color: %2; border-radius:2px;}""QLineEdit:hover{border-width:1px; border-style:solid; border-color:%3; background-color:%3;}""QLineEdit:focus{border-width:1px; border-style:solid; border-color:%4; background-color:%5; }").arg(getFill1().name(QColor::HexArgb)).arg(getWhite1().name(QColor::HexArgb)).arg(getFill2().name(QColor::HexArgb)).arg(getBrand1().name(QColor::HexArgb)).arg(getFill5().name(QColor::HexArgb)));connect(renameEdit_, &QLineEdit::editingFinished, this, [this]() {QString newName = renameEdit_->text();if (!newName.isEmpty() && newName != name_) {emit sigNameChanged(name_, newName);}});connect(renameEdit_, &QLineEdit::returnPressed, this, [this]() {QString newName = renameEdit_->text();if (!newName.isEmpty() && newName != name_) {emit sigNameChanged(name_, newName);}renameEdit_->setVisible(false);elidedName(nameLabel_, name_);});
}void JsonListItem::elidedName(QLabel* label, const QString& name) {QFontMetrics fontWidth(label->font());int contentWidth = label->width() - label->document()->documentMargin() * 2;label->setText(fontWidth.elidedText(name, Qt::ElideRight, contentWidth));label->setFixedHeight(24);
}

JsonListWidgetItem.h

#pragma once#include <QListWidgetItem>enum ItemRole {kRoleId = Qt::UserRole + 1,kRoleIndex,kRoleNumber,kRoleMainFlag,kRoleStatus,kRoleErrorCode,kRoleTime,kRoleName,
};class JsonWidgetItem : public QListWidgetItem {
public:virtual bool operator<(const QListWidgetItem &other) const override;private:bool checked_;
};

JsonListWidgetItem.cpp

#include "JsonWidgetItem.h"
#include "JsonWidget.h"
#include <QListWidget>
#include <shlwapi.h>
#include "PlayerItemDataDef.h"JsonWidgetItem::JsonWidgetItem(QListWidget *listview) : QListWidgetItem(listview), checked_(false) {}JsonWidgetItem::~JsonWidgetItem() {}bool JsonWidgetItem::operator<(const QListWidgetItem &other) const {if (auto listView = qobject_cast<JsonWidget *>(listWidget())) {if (listView->sortFactor() == kFactorNumber) {return data(kRoleNumber).toInt() < other.data(kRoleNumber).toInt();} else if (listView->sortFactor() == kFactorName) {return StrCmpLogicalW((PCWSTR)data(kRoleName).toString().utf16(),(PCWSTR)other.data(kRoleName).toString().utf16()) == -1;} else if (listView->sortFactor() == kFactorTime) {if (data(kRoleMainFlag).toBool()) {return true;} else if (other.data(kRoleMainFlag).toBool()) {return false;} else {return data(kRoleTime).toULongLong() < other.data(kRoleTime).toULongLong();}}}return data(kRoleNumber).toString().compare(other.data(kRoleNumber).toString()) < 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/5954.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Buildroot 取消默认QT桌面-迅为RK3588开发板

本小节将讲解如何取消掉默认的 qt 桌面。 首先对开发板进行上电&#xff0c;开发板正常启动后&#xff0c;使用命令“cd /etc/init.d”进入到/etc/init.d 目录 下&#xff0c;然后使用以下命令对开机自启动脚本 rcS 进行查看&#xff0c;如下图所示&#xff1a; vi rcS 从上…

B2a实例学习记录

B2a简介 只是把hit存到了hitcollection&#xff0c;只是统计了各自event结果&#xff0c;将每次event的运行结果存起来了&#xff0c;并没有做总的求和 如何在B2a的基础上&#xff0c;实现对某一个chamber的能量的累加 1 hit和SD&#xff08;sensitive detector) 每一个s…

minikube从入门到精通系列之一:部署minikube详细步骤

minikube从入门到精通系列之一&#xff1a;部署minikube详细步骤 一、认识Minikube二、Minikube核心知识点三、minikube官方地址四、minikube 启动五、minikube的配置需求六、Mac安装minikube七、CenotOS7上安装minikube八、启动集群九、与集群交互十、部署应用程序1.Service2.…

服务器压力测试

目录 一、磁盘性能测试安装fio磁盘性能测试工具测试内容为顺序读、随机读、顺序写、随机写、随机读写结果分析 二、CPU性能测试安装sysbench性能测试工具结果分析 三、内存性能测试结果分析 四、网络性能测试测试iperf3工具测试结果分析1.测试TCP吞吐量2 . 测试UDP丢包和延迟 此…

自定义MVC框架优化

目录 一、前言 二、优化问题 1.子控制器的初始化配置问题 2.页面跳转优化代码冗余问题 3.优化参数封装问题 三、进行优化 1.解决子控制器初始化配置 2.解决页面跳转的代码冗余问题 3.解决优化参数封装问题 4.中央控制器 一、前言 在自定义MVC框架原理中讲述了什么是…

基于matlab使用点特征匹配稳定从抖动平台捕获的视频(附源码)

一、前言 此示例演示如何稳定从抖动平台捕获的视频。稳定视频的一种方法是跟踪图像中的显著特征&#xff0c;并将其用作锚点以消除与其相关的所有扰动。但是&#xff0c;此过程必须了解第一个视频帧中这种显着特征的位置。在此示例中&#xff0c;我们探索了一种无需任何此类先…

亚马逊云科技中国峰会聚焦生成式AI等前沿科技,探讨当下时代的挑战与机遇

6月27日&#xff0c;“2023亚马逊云科技中国峰会”在上海世博中心盛大启幕&#xff01; 亚马逊全球副总裁、亚马逊云科技大中华区执行董事张文翊全面阐述了在当下这个挑战与机遇并存的时代&#xff0c;面对生成式AI等前沿科技带来的新挑战和新机遇&#xff0c;企业需要“面向未…

使用 Docker 高效搭建本地开发环境(详细教程)

Docker本地开发环境的好处 试错 对开发者而言&#xff0c;每天会催生出的各式各样的新技术都需要尝试&#xff0c;然而开发者却不太可能为他们一一搭建好环境并进行测试。时间非常宝贵&#xff0c;正是得益于 Docker&#xff0c;让我们有可能在一条或者几条命令内就搭建完环境…

阿里巴巴开源Chat2DB v1.0.11 初体验

阿里巴巴开源Chat2DB v1.0.11 初体验 前言什么是Chat2DB下载安装安装配置Chat2DB初体验配置数据源准备测试数据认识几个功能菜单开始测试自然语言转SQLSQL解释SQL优化 使用总结后续功能结语 前言 作为一名阿里巴巴开源项目的拥护者&#xff0c;从Chat2DB开源至今都有关注这个开…

Spring 项目过程及如何使用 Spring

文章目录 1.创建 Spring 项目步骤1.1 创建 Maven 项目1.2添加 Spring 框架支持1.3 添加启动项2.如何使用 Spring2.1 存储 Bean 对象2.1.1 创建 Bean对象2.1.2 将 Bean对象注册到容器中 2.2 获取并使用 Bean对象2.2.1 使用 ApplicationContext 获取对象2.2.2 使用 BeanFactory 获…

【裸机开发】GPT 定时器(三) —— 使用GPT实现高精度延时

延时最简单粗暴的方式就是使用空循环来延时&#xff0c;依赖的是时钟主频&#xff08;默认是396M&#xff09;来计数&#xff0c;一旦修改了 6ull 的时钟主频&#xff0c;延时效果就会存在偏差。 因此我们可以使用 EPIT 或者 GPT 的计数功能实现高精度延时&#xff0c;EPIT 是…

探索MediaPipe的人像分割

MediaPipe是Google开源的计算机视觉处理框架&#xff0c;基于TensorFlow来训练模型。图像分割模块提供人像分割、头发分割、多类分割。本文主要探索如何实现人像分割&#xff0c;当然在人像分割基础上&#xff0c;我们可以做背景替换、背景模糊。 目录 一、配置参数与模型 1…