MixWithComboxInput.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "MixWithComboxInput.h"
  2. #include <QComboBox>
  3. #include <QLabel>
  4. #include <QHBoxLayout>
  5. #include <QPainter>
  6. #include <QAbstractItemView>
  7. #include <QKeyEvent>
  8. class MixWithComboxInput::Private
  9. {
  10. public:
  11. QComboBox *combo;
  12. QLabel *label;
  13. bool inside;
  14. bool isFlat;
  15. };
  16. MixWithComboxInput::MixWithComboxInput(QWidget *parent) : QStackedWidget(parent), d(new Private)
  17. {
  18. #ifdef Q_OS_MACOS
  19. setAttribute(Qt::WA_MacMiniSize, true);
  20. #endif
  21. QWidget *first = new QWidget(this);
  22. QHBoxLayout *layout = new QHBoxLayout(first);
  23. layout->setSpacing(0);
  24. layout->setMargin(0);
  25. d->label = new QLabel(first);
  26. d->label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
  27. layout->addWidget(d->label, 10);
  28. QLabel *icon = new QLabel(first);
  29. QStyleOption option;
  30. option.state = QStyle::State_Enabled;
  31. QPixmap pixmap(16, 16);
  32. pixmap.fill(QColor(255, 255, 255, 0));
  33. QPainter painter(&pixmap);
  34. painter.translate(8, 8);
  35. style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter);
  36. icon->setPixmap(pixmap);
  37. layout->addWidget(icon);
  38. addWidget(first);
  39. d->combo = new QComboBox(this);
  40. d->combo->setMaxVisibleItems(15);
  41. d->combo->setEditable(true);
  42. d->combo->installEventFilter(this);
  43. addWidget(d->combo);
  44. d->inside = false;
  45. d->isFlat = true;
  46. connect(d->combo, SIGNAL(activated(QString)), this, SIGNAL(inputLevelChanged(QString)));
  47. connect(d->combo, SIGNAL(activated(QString)), this, SLOT(setCurrentInputLevel(QString)));
  48. }
  49. MixWithComboxInput::~MixWithComboxInput()
  50. {
  51. delete d;
  52. }
  53. void MixWithComboxInput::enterEvent(QEvent *event)
  54. {
  55. Q_UNUSED(event);
  56. d->inside = true;
  57. if (!isFlat()) {
  58. return;
  59. }
  60. if (d->combo->view()) {
  61. d->combo->view()->removeEventFilter(this);
  62. }
  63. setCurrentIndex(1);
  64. }
  65. void MixWithComboxInput::leaveEvent(QEvent *event)
  66. {
  67. Q_UNUSED(event);
  68. d->inside = false;
  69. if (!isFlat()) {
  70. return;
  71. }
  72. if (d->combo->view() && d->combo->view()->isVisible()) {
  73. d->combo->view()->installEventFilter(this);
  74. return;
  75. }
  76. if (!d->combo->hasFocus())
  77. setCurrentIndex(0);
  78. }
  79. void MixWithComboxInput::keyPressEvent(QKeyEvent *event)
  80. {
  81. if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
  82. focusNextChild();
  83. }
  84. }
  85. bool MixWithComboxInput::isFlat() const
  86. {
  87. return d->isFlat;
  88. }
  89. void MixWithComboxInput::setFlat(bool flat)
  90. {
  91. if (flat == d->isFlat) {
  92. return;
  93. }
  94. d->isFlat = flat;
  95. if (flat) {
  96. d->combo->installEventFilter(this);
  97. if (d->inside) {
  98. enterEvent(nullptr);
  99. } else {
  100. leaveEvent(nullptr);
  101. }
  102. d->combo->setEditable(true);
  103. } else {
  104. d->combo->removeEventFilter(this);
  105. if (d->combo->view()) {
  106. d->combo->view()->removeEventFilter(this);
  107. }
  108. d->combo->setCurrentIndex(d->combo->findText(d->label->text()));
  109. d->combo->setEditable(false);
  110. setCurrentIndex(1);
  111. }
  112. }
  113. void MixWithComboxInput::setInputLevels(const QStringList &levels)
  114. {
  115. d->combo->clear();
  116. d->combo->addItems(levels);
  117. }
  118. void MixWithComboxInput::setCurrentInputLevel(const QString &level)
  119. {
  120. d->combo->setCurrentIndex(d->combo->findText(level));
  121. d->label->setText(level);
  122. }
  123. bool MixWithComboxInput::eventFilter(QObject *watched, QEvent *event)
  124. {
  125. if (watched == d->combo->view() && event->type() == QEvent::Hide) {
  126. focusNextChild();
  127. setCurrentIndex(0);
  128. } else if (watched == d->combo && event->type() == QEvent::FocusOut
  129. && (d->combo->view() && !d->combo->view()->hasFocus()) && !d->inside) {
  130. setCurrentIndex(0);
  131. }
  132. return false;
  133. }