(Qt项视图Demo)ListWidget简单使用搜索记录窗体

可自己复用自己改造的ListWidget使用demo

使用的话可以和给外部QLineEdit搭配,接受sigSelectRecord即可

其他类似的均可由这个基础demo改造

 头文件.h

//搜索记录工具
class GLEXPORT SearchRecordWidget : public QWidget{
  Q_OBJECT
 public:
  SearchRecordWidget(QWidget* wid = nullptr);
  ~SearchRecordWidget();

  //添加一项
  void addItem(QString);
  //清空所有item
  void clearAllItem();
  //获取listwidget行数
  int recordCount(){return m_list_widget->count();};

 protected:
  void mouseMoveEvent(QMouseEvent* event) override;

signals:
  //选中某个字符串
  void sigSelectItem(QString); 
    void sigSelectRecord(QString);

 private:
  void InitUi();
  //根据listWidget适配高度
  void adjustHeight();
  //清除所有item的悬浮状态
  void clearAllItemHoverState();


protected:
   bool eventFilter(QObject*, QEvent*) override;
   void paintEvent(QPaintEvent*) override;

private slots:

private:
   QLabel*      m_lab_title{nullptr};
   QPushButton* m_btn_clear{nullptr};
   QListWidget* m_list_widget{nullptr};

   //窗体固定宽度
   int m_fix_w{173};
   //list每项的行高
   int m_list_item_h{24};
   //除listwidegt以上的高度
   int m_top_height {32};
};

class QHBoxLayout;
class SearchRecordItemWidget : public QWidget {
  Q_OBJECT
 public:
  SearchRecordItemWidget(QString, QWidget* parent = nullptr);
  ~SearchRecordItemWidget();

  //设置悬浮状态
  void setHoverState(bool);
  QString getRecordText(){return m_text;};

 private:
  void InitUi();

 protected:
  virtual void enterEvent(QEvent* event);
  virtual void leaveEvent(QEvent* event);
  virtual void mouseReleaseEvent(QMouseEvent* event);
 signals:
  void sigDeleteItem();
  void sigSelectRecord(QString);

 private:
  QWidget*     m_wid_main {nullptr};
  QLabel*      m_lab_text{nullptr};
  QString      m_text{""};
  QPushButton* m_btn_clear{nullptr};
  //水平布局,放入类全局便于控制按钮的加入
  QHBoxLayout*m_hor_layout{nullptr};
};

实现文件.cpp

SearchRecordWidget::SearchRecordWidget(QWidget* wid) : QWidget(wid){
    InitUi();
}
SearchRecordWidget::~SearchRecordWidget() {}

void SearchRecordWidget::addItem(QString str) {
  int count = m_list_widget->count();
  //大于8个删除最后一行
  if (count >= 8) {
    m_list_widget->takeItem(count - 1);
  }
  //插入Item
  QListWidgetItem* item = new QListWidgetItem(NULL);
  m_list_widget->insertItem(0, item);
  //生成ItemWidget
  SearchRecordItemWidget* formatWidget =
      new SearchRecordItemWidget(str, this);
  formatWidget->setFocusPolicy(Qt::NoFocus);
  //给Item设置和ItemWidget一样的大小
  QSize formatSize = QSize(m_list_widget->width(), m_list_item_h);
  item->setSizeHint(formatSize);
  m_list_widget->setItemWidget(item, formatWidget);

  connect(formatWidget, &SearchRecordItemWidget::sigDeleteItem, this,
          [this]() {
            QObject* obj = sender();
            if (obj) {
              int need_row = -1;
              //找到第几行,删除即可
              int count = m_list_widget->count();
              for (int i = 0; i < count; i++) {
                auto cur_item = this->m_list_widget->item(i);
                QWidget* cur_wid = m_list_widget->itemWidget(cur_item);
                if (cur_wid == obj) {
                  need_row = i;
                  break;
                }
              }
              if (need_row != -1) {
                m_list_widget->takeItem(need_row);
                if (m_list_widget->count() == 0) {
                  //没有行了,关闭本窗体
                  close();
                } else {
                  //还有行,适配高度
                  adjustHeight();
                }
              }
            }
          });

  connect(formatWidget, &SearchRecordItemWidget::sigSelectRecord, this,
          [this](QString str) {
            emit sigSelectRecord(str);
            close();
          });

  //大小适配
  adjustHeight();
}

void SearchRecordWidget::clearAllItem() { 
  m_list_widget->clear();
  adjustHeight();
  hide();
}

void SearchRecordWidget::mouseMoveEvent(QMouseEvent* event) {





}

void SearchRecordWidget::InitUi() {
  //设置弹窗属性
  //无边框+顶层
  this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint |
                       Qt::WindowStaysOnTopHint);
#ifdef __APPLE__
  this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
#endif
  //大小
  this->setFixedSize(m_fix_w, m_top_height);
  //this->setFocusPolicy(Qt::NoFocus);

  QFont font_10;
  font_10.setPixelSize(10);
  //最近搜索文字
  m_lab_title = new QLabel(this);
  m_lab_title->setFixedSize(QSize(40, 14));
  m_lab_title->move(14, 9);
  m_lab_title->setText(QString::fromUtf8("最近搜索"));
  m_lab_title->setFont(font_10);
  //清空按钮
  m_btn_clear = new QPushButton(this);
  m_btn_clear->setFixedSize(25, 15);
  m_btn_clear->move(140, 9);
  m_btn_clear->setText(QString::fromUtf8("清空"));
  m_btn_clear->setFont(font_10);
  connect(m_btn_clear, &QPushButton::clicked, [this](bool) { 
      clearAllItem();
  });

  //记录列表
  m_list_widget = new QListWidget(this);
  m_list_widget->move(6, m_top_height);
  m_list_widget->setFixedSize(m_fix_w-6-6, 0);
  m_list_widget->clear();
  m_list_widget->setFocusPolicy(Qt::NoFocus);
  m_list_widget->setSpacing(0);
  m_list_widget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  m_list_widget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  m_list_widget->setMouseTracking(true);
  m_list_widget->installEventFilter(this);

  this->setMouseTracking(true);
  installEventFilter(this);
}

void SearchRecordWidget::paintEvent(QPaintEvent*) {
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void SearchRecordWidget::adjustHeight() {
  int count = m_list_widget->count();
  //每项高24
  int add_height = count * m_list_item_h;
  m_list_widget->setFixedHeight(add_height);
  this->setFixedHeight(m_top_height + add_height+5);
}

void SearchRecordWidget::clearAllItemHoverState() {
  int count = m_list_widget->count();
  for (int i = 0; i < count; i++) {
    auto cur_item = this->m_list_widget->item(i);
    QWidget* cur_wid = m_list_widget->itemWidget(cur_item);
    SearchRecordItemWidget* cur_item_wid = (SearchRecordItemWidget*)cur_wid;
    cur_item_wid->setHoverState(false);
  }
}

bool SearchRecordWidget::eventFilter(QObject* obj, QEvent* event) {
  if (obj == this) {
    if (event->type() == QEvent::WindowDeactivate) {
      hide();
    } else if (event->type() == QEvent::Leave) {
      hide();
    }
  }

   if (obj == this->m_list_widget) {
    if (event->type() == QEvent::MouseMove) {
      //auto item = this->m_list_widget->itemAt(
      //    this->m_list_widget->viewport()->mapFromGlobal(this->cursor().pos()));
      //QWidget* need_wid = m_list_widget->itemWidget(item);
      //SearchRecordItemWidget* item_wid = (SearchRecordItemWidget*)need_wid;

      //if (item_wid != nullptr) {
      //  //遍历所有项,除item_wid外所有项都变成不可选择项
      //  int count = m_list_widget->count();
      //  for (int i = 0; i < count; i++) {
      //    auto cur_item = this->m_list_widget->item(i);
      //    QWidget* cur_wid = m_list_widget->itemWidget(cur_item);
      //    SearchRecordItemWidget* cur_item_wid =
      //        (SearchRecordItemWidget*)cur_wid;
      //    if (cur_item_wid == item_wid) {
      //      cur_item_wid->setHoverState(true);
      //    } else {
      //      cur_item_wid->setHoverState(false);
      //    }
      //  }
      //}
    } else if (event->type() == QEvent::Leave) {
      clearAllItemHoverState();
    }
  }

  return false;
}


SearchRecordItemWidget::SearchRecordItemWidget(QString str, QWidget* parent)
    : QWidget(parent) {
    m_text = str;
    InitUi();
    setHoverState(false);
}

SearchRecordItemWidget::~SearchRecordItemWidget() {}

void SearchRecordItemWidget::setHoverState(bool is_hover) {
  if (is_hover) {
    //选择状态
    m_btn_clear->show();
    m_hor_layout->addWidget(m_btn_clear);
    QString style = "border-radius:5px;background-color:";
    style+=BFSKIN()->getColor(BFSkinSetting::KUEBtnNormalCancelColor);
    style += ";";
    m_wid_main->setStyleSheet(style);
  } else {
    //普通状态
    m_hor_layout->removeWidget(m_btn_clear);
    m_btn_clear->hide();
    m_wid_main->setStyleSheet("background-color:rgba(0,0,0,0);");
  }
}

void SearchRecordItemWidget::InitUi() {
  //main——widget
  QGridLayout* grid_layout = new QGridLayout(this);
  grid_layout->setContentsMargins(0,0,0,0);
  this->setLayout(grid_layout);

  //主窗体
  m_wid_main = new QWidget(this);
  grid_layout->addWidget(m_wid_main);

  //水平layout
  m_hor_layout = new QHBoxLayout(m_wid_main);
  m_hor_layout->setContentsMargins(8, 0, 6, 0);
  m_hor_layout->setSpacing(10);
  m_wid_main->setLayout(m_hor_layout);

  //项文字
  m_lab_text = new QLabel(this);
  m_lab_text->setText(m_text);
  m_lab_text->setAlignment(Qt::AlignVCenter);
  m_hor_layout->addWidget(m_lab_text);
  //m_lab_text->setStyleSheet("background-color:rgba(255,0,0,100);");

  //清除按钮
  m_btn_clear = new QPushButton(this);
  m_btn_clear->setFixedSize(12,12);
  m_hor_layout->addWidget(m_btn_clear);
  connect(m_btn_clear, &QPushButton::clicked, this,
          [this](bool) { emit sigDeleteItem(); });
}

void SearchRecordItemWidget::enterEvent(QEvent* event) {
  setHoverState(true);
}

void SearchRecordItemWidget::leaveEvent(QEvent* event) {
  setHoverState(false);
}

void SearchRecordItemWidget::mouseReleaseEvent(QMouseEvent* event) {
  emit sigSelectRecord(m_text);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值