logplus/qtpropertybrowser/qtComboBox.cpp
DESKTOP-450PEFP\mainc 506cecf05c 添加 左侧属性色板属性的实现,显示色板列表
修改波列显示效果,显示颜色对应旧版logplus
添加波形部分属性修改,左刻度,右刻度,显示名称,显示单位字体属性,色板,变密度颜色级数等属性
修改波形属性修改完后保存文件,读取保存的属性显示效果
2026-02-04 12:16:25 +08:00

531 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file QtComboBox.cpp
* @date 2011-10-17
*/
#include <QStyledItemDelegate>
#include <QApplication>
#include <QPainter>
#include <QValidator>
#include <QKeyEvent>
#include <QLineEdit>
#include <QPaintEvent>
#include <QDesktopWidget>
#include <QFontMetrics>
#include <QAbstractItemView>
#include "qtComboBox.h"
/**
* @class QtComboBoxItemDelegate
* @brief 用来绘制ComboBox弹出选择框Item
*/
class QTPROPERTYBROWSER_EXPORT QtComboBoxItemDelegate : public QStyledItemDelegate
{
public:
QtComboBoxItemDelegate(QObject *pParent = 0) :
QStyledItemDelegate(pParent)
{
}
protected:
/**
* @brief 重新实现重绘函数
* @param[in] pPainter 画笔
* @param[in] option 类型选项
* @param[in] index Model 索引
*/
void paint(QPainter *pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
opt.state = opt.state & ~QStyle::State_Selected;
if((option.state & QStyle::State_Selected) && (option.state & QStyle::State_Enabled))
{
QLinearGradient linearGrad(opt.rect.topLeft(), opt.rect.bottomLeft());
linearGrad.setColorAt(0, QColor("#FFFFFF"));
linearGrad.setColorAt(1, QColor("#EAF2F4"));
opt.backgroundBrush = QBrush(linearGrad);
}
else
{
opt.backgroundBrush = QBrush("#EFF5FA");
}
const QWidget *pWidget = opt.widget;
if(pWidget == NULL)
{
return;
}
QStyle *pStyle = pWidget ? pWidget->style() : QApplication::style();
pStyle->drawControl(QStyle::CE_ItemViewItem, &opt, pPainter, pWidget);
if((option.state & QStyle::State_Selected) && (option.state & QStyle::State_Enabled))
{
pPainter->save();
pPainter->setPen(QColor("#AACEDB"));
pPainter->drawRoundedRect(option.rect.adjusted(1, 1, -2, -2), 1, 1);
pPainter->restore();
}
}
/**
* @brief 重设高度
* @param[in] option 类型选项
*/
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & /*index*/) const
{
return QSize(option.rect.width(), 24);
}
};
/////////////////////////////////////////////////////////////////////
QtComboBox::QtComboBox(QWidget *pParent) :
QComboBox(pParent),
m_AddButton(false)
{
InitComboBox();
}
QtComboBox::QtComboBox(bool showAddButton, QWidget *pParent)
: QComboBox(pParent),
m_AddButton(showAddButton)
{
InitComboBox();
SetShowAddButton(m_AddButton);
}
QtComboBox::~QtComboBox()
{
}
void QtComboBox::InitComboBox()
{
m_pEditButton = NULL;
m_RealTimeValidate = false;
m_MaxVisibleItems = 10; // 默认显示10个
QAbstractItemView *pView = view();
// 将view初始设置为最小防止调整位置和大小时闪烁
pView->parentWidget()->setFixedSize(QSize(0, 0));
pView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
// 当Item文本过长则在右侧用“...”代替
pView->setTextElideMode(Qt::ElideRight);
const QObjectList objs = view()->parentWidget()->children ();
// 隐藏多余控件
foreach(QObject *pObj, objs)
{
QWidget *pWgt = qobject_cast<QWidget*>(pObj);
if(pWgt && (pWgt != pView))
{
pWgt->setMaximumHeight(0);
}
}
setItemDelegate(new QtComboBoxItemDelegate(this));
}
void QtComboBox::SetShowAddButton(bool show)
{
if (show && m_pEditButton == NULL)
{
m_AddButton = true;
m_pEditButton = new QToolButton(this);
m_pEditButton->setIcon(QIcon(":/Edit.png"));
m_pEditButton->setStyleSheet(
"QToolButton{ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
"stop: 0.0 #FFFFFF, stop: 0.4 #F7FAFD,stop: 0.4 #E5EFF8, stop: 1.0 #BDD7EC);"
"border: 1px solid #839CB6; border-left:0px;"
"border-top-right-radius: 2px; border-bottom-right-radius: 2px}"
"QToolButton:hover { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
"stop: 0.0 #F1F9FE, stop: 0.4 #E1F3FC, stop: 0.4 #C9E9F9, stop: 1.0 #9BD7F1);}"
"QToolButton:focus { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
"stop: 0 #E6F5FB, stop: 0.38 #D0ECF8, stop: 0.39 #AADDF2, stop: 1.0 #70C5EA);}"
);
connect(m_pEditButton, SIGNAL(clicked()), this, SIGNAL(EditButtonClicked()));
}
else if(!show && m_pEditButton)
{
// 去掉按钮所占空间
setStyleSheet(QString::fromUtf8("QComboBox{margin-right:0px}"));
m_pEditButton->hide();
}
}
void QtComboBox::showPopup ()
{
QComboBox::showPopup();
if(count() == 0)
{
return;
}
// 每条Item的高度为24;
const int ITEM_HEIGHT = 24;
int popWidgetHeight = ITEM_HEIGHT * (m_MaxVisibleItems < count() ? m_MaxVisibleItems : count()) + 2;
QPoint popWidgetPos(0, 0);
// 屏幕高度
int iHeightOfScreen = QApplication::desktop()->height();
// 下方空间高度
int iBottomSpace = iHeightOfScreen - mapToGlobal(rect().bottomLeft()).y();
// 上方空间高度
int iTopSpace = mapToGlobal(rect().topLeft()).y();
if(iBottomSpace >= popWidgetHeight) //如果下方区域足够显示选择列表则在下方显示
{
popWidgetPos = mapToGlobal(rect().bottomLeft()) - QPoint( -m_margin.left(), m_margin.bottom());
}
else if(iTopSpace >= popWidgetHeight) //如果下方空间不足,而上方空间充足,则上方显示
{
popWidgetPos = mapToGlobal(rect().topLeft()) - QPoint(0, popWidgetHeight) + QPoint(m_margin.left(), m_margin.top());
}
else // 如果上下空间都不足,则调整显示条数
{
if(iBottomSpace > iTopSpace)
{
popWidgetHeight = iBottomSpace;
popWidgetPos = mapToGlobal(rect().bottomLeft()) - QPoint( -m_margin.left(), m_margin.bottom());
}
else
{
popWidgetHeight = iTopSpace;
popWidgetPos = mapToGlobal(rect().topLeft()) - QPoint(0, popWidgetHeight) + QPoint(m_margin.left(), m_margin.top());
}
}
// 调整view的位置和大小
QAbstractItemView *pView = view();
if(pView && pView->parentWidget())
{
pView->parentWidget()->setFixedHeight(popWidgetHeight);
pView->parentWidget()->move(popWidgetPos);
int minWidth = rect().width() - m_margin.left() - m_margin.right();
int widthOfScreen = QApplication::desktop()->width();
// 如果ComboBox的宽度小于屏幕三分之一根据每行Item文字长度调节下拉框宽度
if(rect().width() < widthOfScreen / 3)
{
// 根据每行Item文字长度确定List的最小宽度
QFontMetrics metrics(pView->font());
QString text;
for(int i = 0; i < count(); i++)
{
text = itemText(i) + " ";//添空格为边框占位
minWidth = minWidth > metrics.width(text) ? minWidth : metrics.width(text);
}
// 如果下拉框宽度超过显示屏宽度三分之一,则将其宽度设置为屏幕宽度的三分之一
if(minWidth > widthOfScreen / 3)
{
minWidth = widthOfScreen / 3;
}
}
pView->parentWidget()->setFixedWidth(minWidth);
}
}
int QtComboBox::GetMaxVisibleItems() const
{
return m_MaxVisibleItems;
}
void QtComboBox::SetMaxVisibleItems(const int count)
{
m_MaxVisibleItems = count;
}
void QtComboBox::setStyleSheet(const QString & styleSheet)
{
QComboBox::setStyleSheet(styleSheet);
QRegExp reg("(margin)\\s*:\\s*\\d+\\s*(px)(.*);");
int offset = styleSheet.toLower().indexOf(reg);
if(offset != -1)
{
int end = styleSheet.indexOf(";", offset);
QString str = styleSheet.mid(offset, end - offset);
QStringList items = str.split(" ");
if(items.size() == 1)
{
QRegExp num("(\\d+)");
int pos = num.indexIn(items[0]);
QString value;
if (pos > -1)
{
value = num.cap(1);
}
bool ok;
int margin = value.toInt(&ok, 10);
if(ok)
{
m_margin = QMargins(margin, margin, margin, margin);
}
}
else if(items.size() == 4)
{
QRegExp num("(\\d+)");
int pos;
bool ok;
QString value;
int left, top, right, bottom;
pos = num.indexIn(items[0]);
if (pos > -1)
{
value = num.cap(1);
}
left = value.toInt(&ok, 10);
if(!ok)
{
return;
}
pos = num.indexIn(items[1]);
if (pos > -1)
{
value = num.cap(1);
}
top = value.toInt(&ok, 10);
if(!ok)
{
return;
}
pos = num.indexIn(items[2]);
if (pos > -1)
{
value = num.cap(1);
}
right = value.toInt(&ok, 10);
if(!ok)
{
return;
}
pos = num.indexIn(items[3]);
if (pos > -1)
{
value = num.cap(1);
}
bottom = value.toInt(&ok, 10);
if(!ok)
{
return;
}
m_margin = QMargins(left, top, right, bottom);
}
}
else
{
int left;
QRegExp regLeft("(margin-left)\\s*:\\s*\\d+\\s*(px)\\s*;");
offset = styleSheet.toLower().indexOf(regLeft);
if(offset == -1)
{
left = 0;
}
else
{
int end = styleSheet.indexOf(";", offset);
QString str = styleSheet.mid(offset, end - offset);
QRegExp num("(\\d+)");
int pos = num.indexIn(str);
QString value;
if (pos > -1)
{
value = num.cap(1);
}
bool ok;
int margin = value.toInt(&ok, 10);
if(ok)
{
left = margin;
}
}
int top;
QRegExp regTop("(margin-top)\\s*:\\s*\\d+\\s*(px)\\s*;");
offset = styleSheet.toLower().indexOf(regTop);
if(offset == -1)
{
top = 0;
}
else
{
int end = styleSheet.indexOf(";", offset);
QString str = styleSheet.mid(offset, end - offset);
QRegExp num("(\\d+)");
int pos = num.indexIn(str);
QString value;
if (pos > -1)
{
value = num.cap(1);
}
bool ok;
int margin = value.toInt(&ok, 10);
if(ok)
{
top = margin;
}
}
int right;
QRegExp regRight("(margin-right)\\s*:\\s*\\d+\\s*(px)\\s*;");
offset = styleSheet.toLower().indexOf(regRight);
if(offset == -1)
{
right = 0;
}
else
{
int end = styleSheet.indexOf(";", offset);
QString str = styleSheet.mid(offset, end - offset);
QRegExp num("(\\d+)");
int pos = num.indexIn(str);
QString value;
if (pos > -1)
{
value = num.cap(1);
}
bool ok;
int margin = value.toInt(&ok, 10);
if(ok)
{
right = margin;
}
}
int bottom;
QRegExp regBottom("(margin-top)\\s*:\\s*\\d+\\s*(px)\\s*;");
offset = styleSheet.toLower().indexOf(regBottom);
if(offset == -1)
{
bottom = 0;
}
else
{
int end = styleSheet.indexOf(";", offset);
QString str = styleSheet.mid(offset, end - offset);
QRegExp num("(\\d+)");
int pos = num.indexIn(str);
QString value;
if (pos > -1)
{
value = num.cap(1);
}
bool ok;
int margin = value.toInt(&ok, 10);
if(ok)
{
bottom = margin;
}
}
m_margin = QMargins(left, top, right, bottom);
}
}
void QtComboBox::SetRealTimeValidate(bool flag)
{
m_RealTimeValidate = flag;
}
void QtComboBox::keyPressEvent(QKeyEvent *pEvent)
{
if(pEvent->key() == Qt::Key_Return)
{
QComboBox::keyPressEvent(pEvent);
pEvent->accept(); // 过滤事件,使其不往父窗体传递
return;
}
if((!m_RealTimeValidate) || (pEvent->key() == Qt::Key_Backspace) || (pEvent->key() == Qt::Key_Delete))
{
QComboBox::keyPressEvent(pEvent);
return;
}
QString currentStr = currentText();
QLineEdit *pLineEdit = lineEdit();
QString selectedText = pLineEdit->selectedText();
QString pressAfterStr;
int pos = pLineEdit->cursorPosition();
if(selectedText.isEmpty())
{
pressAfterStr = currentStr.insert(pos, pEvent->text());
}
else
{
pressAfterStr = currentStr.replace(pLineEdit->selectionStart(), selectedText.size(), pEvent->text());
}
const QValidator *pValidator = validator();
int postion = pressAfterStr.size();
if(pValidator && (pValidator->validate(pressAfterStr, postion) == QValidator::Invalid))
{
pEvent->accept();
}
else
{
QComboBox::keyPressEvent(pEvent);
}
return;
}
void QtComboBox::resizeEvent(QResizeEvent *pEvent)
{
QComboBox::resizeEvent(pEvent);
// 请不要添加m_pEditButton->isVisible()条件因为没有paint之前控件是不可见的
if(m_AddButton && m_pEditButton)
{
// 为按钮所准备空间
setStyleSheet(QString::fromUtf8("QComboBox{margin-right:%1px}").arg(height()));
}
}
void QtComboBox::paintEvent(QPaintEvent *pEvent)
{
QComboBox::paintEvent(pEvent);
if(m_AddButton && m_pEditButton && m_pEditButton->isVisible())
{
// 添加限制条件确保这里不会频繁的调用
QRect rect(width()-height() - 1, 0, height() + 1, height());
if(m_pEditButton->geometry() != rect)
{
m_pEditButton->setGeometry(rect);
}
QPainter painter(this);
painter.setPen(QColor("#839CB6"));
painter.drawLine(width()-height() - 2, 6, width() - height() - 2, height() - 6);
}
}