通过对Combox选项进行修改,使用QStandardItemModel存储选项模型。
MenuItem.h
1. #ifndef MENUITEM_H
2. #define MENUITEM_H
3.
4. #include <QObject>
5.
6. class MenuItem
7. {
8. public:
9. MenuItem(int iMenuId, const QString &strMenuName, bool bIsChecked = false);
10. MenuItem();
11. ~MenuItem();
12.
13. MenuItem(const MenuItem &menuItem);
14. int GetMenuId() const;
15. void SetMenuId(int iValue);
16.
17. QString GetMenuName() const;
18. void SetMenuName(const QString &strValue);
19.
20. bool GetIsChecked() const;
21. void SetIsChecked(bool bValue);
22.
23. private:
24. int m_iMenuId;
25. QString m_strMenuName;
26. bool m_bIsChecked;
27.
28. };
29.
30. #endif // MENUITEM_H
MenuItem.cpp
1. #include "MenuItem.h"
2.
3.
4. MenuItem::MenuItem(int iMenuId, const QString &strMenuName, bool bIsChecked /* = false */)
5. :m_iMenuId(iMenuId)
6. ,m_strMenuName(strMenuName)
7. ,m_bIsChecked(bIsChecked)
8. {
9.
10. }
11.
12. MenuItem::MenuItem()
13. {
14. m_iMenuId = -1;
15. m_strMenuName = QString("");
16. m_bIsChecked = false;
17. }
18.
19. MenuItem::MenuItem(const MenuItem &menuItem)
20. {
21. m_iMenuId = menuItem.GetMenuId();
22. m_strMenuName = menuItem.GetMenuName();
23. m_bIsChecked = menuItem.GetIsChecked();
24. }
25.
26. MenuItem::~MenuItem()
27. {
28. }
29.
30. int MenuItem::GetMenuId() const
31. {
32. return m_iMenuId;
33. }
34.
35. void MenuItem::SetMenuId(int iValue)
36. {
37. m_iMenuId = iValue;
38. }
39.
40. QString MenuItem::GetMenuName() const
41. {
42. return m_strMenuName;
43. }
44.
45. void MenuItem::SetMenuName(const QString &strValue)
46. {
47. m_strMenuName = strValue;
48. }
49. // 返回当前控件是否被选中
50. bool MenuItem::GetIsChecked() const
51. {
52. return m_bIsChecked;
53. }
54.
55. void MenuItem::SetIsChecked(bool bValue)
56. {
57. m_bIsChecked = bValue;
58. }
MutiCombox.h
1. #ifndef MULTICOMBOX_H
2. #define MULTICOMBOX_H
3.
4. #include <QWidget>
5. #include <QComboBox>
6.
7. class MenuItem;
8. class QLineEdit;
9. class QListView;
10. class QStandardItemModel;
11.
12. class MultiComBox : public QComboBox
13. {
14. Q_OBJECT
15.
16. public:
17. MultiComBox(QWidget *parent = NULL);
18. ~MultiComBox();
19.
20. //添加Iiem
21. void AddItems(QList<MenuItem*> menus);
22.
23. //移除Item
24. void RemoveItem(int row);
25.
26. void Clear();
27.
28. QStringList GetItemsText();
29.
30. QList<int> GetItemsId();
31.
32. signals:
33. void sigActivated(int row);
34.
35. protected:
36. void hidePopup() override;
37.
38. bool eventFilter(QObject *watched, QEvent *event) override;
39.
40. private:
41. QList<MenuItem> m_Menus;
42. QLineEdit *m_pLineEdit;
43. QListView *m_pListView;
44. QStandardItemModel *m_pItemModel;
45.
46. private:
47. void UpdateText();
48.
49. public slots:
50. void sltActivated(int row);
51. };
52.
53. #endif // MULTICOMBOX_H
MutiCombox.cpp
1. #include "MultiComBox.h"
2. #include "MenuItem.h"
3. #include <QLineEdit>
4. #include <QListView>
5. #include <QStandardItemModel>
6. #include <QMouseEvent>
7.
8. MultiComBox::MultiComBox(QWidget *parent)
9. : QComboBox(parent)
10. {
11. //为 ComBox 设置编辑框
12. m_pLineEdit = new QLineEdit(this);
13. m_pLineEdit->setReadOnly(true);
14. this->setLineEdit(m_pLineEdit);
15.
16. //设置 ComBox 下拉界面
17. m_pListView = new QListView(this);
18. m_pListView->installEventFilter(this);
19. this->setView(m_pListView);
20.
21. //设置 ComBox 数据模型
22. m_pItemModel = new QStandardItemModel(this);
23. this->setModel(m_pItemModel);
24.
25. connect(this, SIGNAL(activated(int)), this, SLOT(sltActivated(int)));
26. }
27.
28. MultiComBox::~MultiComBox()
29. {
30.
31. }
32.
33. //*************************************************
34. //Function: AddItems
35. //Description: 添加下拉菜单内容
36. //Input: menus:菜单内容列表
37. //Return: 若中途执行失败,则返回false,中断操作;否则,返回真,继续后续操作
38. //*************************************************
39. void MultiComBox::AddItems(QList<MenuItem*> menus)
40. {
41. QStandardItem *pNewItem;
42. for each(MenuItem *pMenuItem in menus) {
43. pNewItem = new QStandardItem(pMenuItem->GetMenuName());
44. pNewItem->setCheckState(pMenuItem->GetIsChecked() ? Qt::Checked : Qt::Unchecked);
45. pNewItem->setData(pMenuItem->GetMenuId());
46. m_pItemModel->appendRow(pNewItem);
47. }
48. UpdateText();
49. }
50.
51. void MultiComBox::RemoveItem(int row)
52. {
53. m_pItemModel->removeRow(row);
54. UpdateText();
55. }
56.
57. void MultiComBox::Clear()
58. {
59. m_pItemModel->clear();
60. UpdateText();
61. }
62.
63. QStringList MultiComBox::GetItemsText()
64. {
65. QStringList strs;
66. QString str = m_pLineEdit->text();
67. if (!str.isEmpty()) {
68. strs = str.split(";");
69. }
70. return strs;
71. }
72.
73. QList<int> MultiComBox::GetItemsId()
74. {
75. QList<int> ids;
76. for (int i = 0; i < m_pItemModel->rowCount(); i++) {
77. QStandardItem *item = m_pItemModel->item(i);
78. if (item->checkState() == Qt::Checked) {
79. ids << item->data().toInt();
80. }
81. }
82. return ids;
83. }
84.
85. //*************************************************
86. //Function: hidePopup
87. //Description: 根据鼠标相应位置,判断是否隐藏下拉菜单
88. //*************************************************
89. void MultiComBox::hidePopup()
90. {
91. int width = this->view()->width();
92. int height = this->view()->height();
93. int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
94. int y = QCursor::pos().y() - mapToGlobal(geometry().topLeft()).y() + geometry().y();
95.
96. QRect rectView(0, this->height(), width, height);
97. if (!rectView.contains(x, y)) {
98. QComboBox::hidePopup();
99. }
100. }
101.
102. bool MultiComBox::eventFilter(QObject *watched, QEvent *event)
103. {
104. if (event->type() == QEvent::MouseButtonPress) {
105. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
106. if (mouseEvent->button() == Qt::LeftButton) {
107. QListView *listView = qobject_cast<QListView*>(watched);
108. if (NULL != listView) {
109. int row = listView->currentIndex().row();
110. sltActivated(row);
111. }
112. return true;
113. }
114. }
115. return QComboBox::eventFilter(watched, event);
116. }
117.
118. //*************************************************
119. //Function: UpdateText
120. //Description: 更新lineedit文本
121. //*************************************************
122. void MultiComBox::UpdateText()
123. {
124. QStringList strs;
125. for (int i = 0; i < m_pItemModel->rowCount(); i++) {
126. QStandardItem *item = m_pItemModel->item(i);
127. if (item->checkState() == Qt::Checked) {
128. strs << item->text();
129. }
130. }
131. m_pLineEdit->setText(strs.join(";"));
132. m_pLineEdit->setToolTip(strs.join("\n"));
133. }
134.
135. void MultiComBox::sltActivated(int row)
136. {
137. QStandardItem *item = m_pItemModel->item(row);
138. Qt::CheckState checkState = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked;
139. item->setCheckState(checkState);
140. UpdateText();
141. }
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "menuitem.h"
#include "muticombox.h"
#include <QList>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QList<MenuItem*> listMenuitem;
for(int i = 0; i<10;++i)
{
MenuItem *pMenuitem = new MenuItem(i,QString::number(i),false);
listMenuitem.append(pMenuitem);
}
MultiComBox *pMenuItem = new MultiComBox(this);
pMenuItem->AddItems(listMenuitem);
pMenuItem->setMinimumWidth(200);
}
Widget::~Widget()
{
delete ui;
}
效果图如下: