先上一段代码
#pragma once
#include <QSpinBox>
#include <QWidget>
#include <QObject>
#include <QLineEdit>
#include <QWheelEvent>
#include <QEvent>
#include <QMouseEvent>
class QDateEdit;
class QTimeEdit;
class QDateTimeEdit;
class QDoubleSpinBox;
class QSpinBox;
template<class basic_class>
class QRInputBoxTemplete: public basic_class
{
public:
QRInputBoxTemplete(QWidget* parent = nullptr)
: basic_class(parent)
, m_bClick(false), m_bEnter(false)
, m_innerLineEdit(nullptr)
{
this->setMouseTracking(true);
QList<QObject*> objList = this->children();
for (auto iter = objList.begin(); iter != objList.end(); iter++)
{
//printf("obj name = %s, isWdget = %d\n", (*iter)->objectName(), (*iter)->isWidgetType());
if ((*iter)->isWidgetType())
{
m_innerLineEdit = (QLineEdit*)(*iter);
m_innerLineEdit->installEventFilter(this);
break;
}
}
}
~QRInputBoxTemplete() {};
protected:
void enterEvent(QEvent* event)
{
m_bEnter = true;
if (m_innerLineEdit)
{
m_innerLineEdit->setReadOnly(false);
}
basic_class::enterEvent(event);
}
void leaveEvent(QEvent* event)
{
m_bEnter = false;
m_bClick = false;
if (m_innerLineEdit)
{
m_innerLineEdit->setSelection(0, 0);
m_innerLineEdit->setReadOnly(true);
}
basic_class::leaveEvent(event);
}
void mousePressEvent(QMouseEvent* event)
{
if (!m_bClick) m_bClick = true;
basic_class::mousePressEvent(event);
}
void wheelEvent(QWheelEvent* event)
{
if (!(m_bEnter && m_bClick))
{
event->ignore();
return;
}
basic_class::wheelEvent(event);
}
bool eventFilter(QObject* obj, QEvent* e)
{
if (obj == m_innerLineEdit)
{
if (e->type() == QEvent::MouseButtonPress)
{
if (!m_bClick) m_bClick = true;
}
}
return basic_class::eventFilter(obj, e);
}
private:
bool m_bClick;
bool m_bEnter;
QLineEdit* m_innerLineEdit;
};
//使用时写在其他位置 [总觉得把父类作为模板类型的套路比较野]
void TestFun()
{
QRInputBoxTemplete<QDateTimeEdit>* spinBox = new QRInputBoxTemplete<QDateTimeEdit>(nullptr);
QRInputBoxTemplete<QDateEdit>* spinBox = new QRInputBoxTemplete<QDateEdit>(nullptr);
QRInputBoxTemplete<QTimeEdit>* spinBox = new QRInputBoxTemplete<QTimeEdit>(nullptr);
QRInputBoxTemplete<QDoubleSpinBox>* spinBox = new QRInputBoxTemplete<QDoubleSpinBox>(nullptr);
QRInputBoxTemplete<QSpinBox>* spinBox = new QRInputBoxTemplete<QSpinBox>(nullptr);
}
这里实现的这个模板,主要是为了避免滚轮激活问题。在使用QTableWidget的时候,某些列可能需要输入框,如果没有使用代理的方式,那便是直接将控件直接填充到了指定的cell里面,类似于整形、浮点、日期等输入框,会因为数据滚动而被激活,一旦编辑框被激活了,就会导致滚轮对于表格控件的滚动失效,通过这个模板来统一处理滚轮事件,可以减少代码量。
上面代码中的QLineEdit* m_innerLineEdit
是通过查找对象树,直接定位到了不同空间的编辑框,经过验证5.6.3版本的QDateTimeEdit、QDateEdit、QTimeEdit、QDoubleSpinBox、QSpinBox
这几个控件中只有一个输入编辑框,获取之后再绑定事件过滤器才能忽略滚轮事件。
之所以这么处理,还是参考了几个控件的实现源码,现在这个阶段看以前的笔记,虽然没有更好的办法,但我还是觉得,这样操作有些野。
网友评论