自己设计的数据输入代理控件
#ifndef PAREDITDELEGATE_H
#define PAREDITDELEGATE_H
#include <QItemDelegate>
#include <QModelIndex>
class ParEditDelegate : public QItemDelegate
{
Q_OBJECT
mutable QModelIndex m_index;
protected slots:
void onCloseEditor(QWidget*);public:
public:
void Editsource(const QModelIndex &index);
explicit ParEditDelegate(QObject* parent = nullptr)
: QItemDelegate(parent)
{
connect(this, SIGNAL(closeEditor(QWidget*)), this, SLOT(onCloseEditor(QWidget*)));
}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
};
#endif // PAREDITDELEGATE_H
#include "pareditdelegate.h"
#include <QDebug>
#include <QCheckBox>
#include <QVariant>
#include "parameterinput.h"
#include <QMouseEvent>
#include <QApplication>
#include "mainwindow.h"
#include <QDesktopWidget>
void ParEditDelegate::onCloseEditor(QWidget *)
{
m_index = QModelIndex(); // 关闭编辑框时将当前记录的索引清空
}
void ParEditDelegate::Editsource(const QModelIndex &index)
{
Q_UNUSED(index);
}
//ParEditDelegate::ParEditDelegate(QObject *parent)
//{
//}
//ParEditDelegate::ParEditDelegate()
//{
// connect(this, SIGNAL(closeEditor(QWidget*)), this, SLOT(onCloseEditor(QWidget*)));
//}
QWidget *ParEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QWidget* ret = NULL;
m_index = index; // 记录当前被编辑数据项索引
if( index.column() == 1 )
{
QString ValueType=index.model()->index(index.row(),index.column()+4,index.parent()).data().toString();
bool dotEnable;
if(ValueType == "comb")
{
QComboBox* comboBox = new QComboBox(parent);
QString itemsString = index.model()->index(index.row(), index.column()+2, index.parent()).data(Qt::DisplayRole).toString();
QStringList items = itemsString.split('|');
for(int i = 0; i < items.size(); ++i)
{
comboBox->addItem(items[i].trimmed()); // 使用.trimmed()去除字符串两边的空白字符
}
ret = comboBox;
}
else if(ValueType!="bool")
{
if(ValueType=="float")
{
dotEnable=true;
}
else
{
dotEnable=false;
}
ParameterInput *input;
float MinIndex;
float MaxIndex;
MinIndex =index.model()->index(index.row(),index.column()+2,index.parent()).data().toFloat();
MaxIndex =index.model()->index(index.row(),index.column()+3,index.parent()).data().toFloat();
if(MinIndex<0)
{
input = new ParameterInput(parent, dotEnable, true, false);
}else {
input = new ParameterInput(parent, dotEnable, false, false);
}
QString parname = index.model()->index(index.row(),index.column()-1,index.parent()).data().toString();
float value = index.data().toFloat();
input->setMinMax(MinIndex, MaxIndex);
input->setStepEnable(false);
input->setInitValue("",value);
input->setTitleText(parname + QString(" value setting"));
ret = input;
}
}
else
{
// 其它情况,直接使用父类提供的默认创建编辑器组件方式
ret = QItemDelegate::createEditor(parent, option, index);
}
return ret; //返回创建的编辑器组件
}
void ParEditDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if( index.column() != 1 )
{
editor->setGeometry(option.rect);
}
else
{
if( index.column() == 1 )
{
QString ValueType=index.model()->index(index.row(),index.column()+4,index.parent()).data().toString();
if((ValueType == "float")||(ValueType == "int"))
{
editor->setGeometry(140,100,1000,600);
}
else if(ValueType == "comb")
{
editor->setGeometry(option.rect.x(),option.rect.y(),180,option.rect.height());
}
else
{
editor->setGeometry(option.rect);
}
}
else
{
editor->setGeometry(option.rect);
}
}
Q_UNUSED(option);
Q_UNUSED(index);
}
void ParEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QItemDelegate::setEditorData(editor, index);
}
void ParEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if( index.column() == 1 )
{
QString ValueType=index.model()->index(index.row(),index.column()+4,index.parent()).data().toString();
if(ValueType == "comb")
{
QComboBox* comboBox = dynamic_cast<QComboBox*>(editor);
if(comboBox)
{
model->setData(index, comboBox->currentText(), Qt::EditRole);
}
}
else if(ValueType!="bool")
{
float MinIndex;
float MaxIndex;
MinIndex =index.model()->index(index.row(),index.column()+2,index.parent()).data().toFloat();
MaxIndex =index.model()->index(index.row(),index.column()+3,index.parent()).data().toFloat();
ParameterInput* input = dynamic_cast<ParameterInput*>(editor);
// input->hide();
if(input->result() == QDialog::Accepted)
{
QString Strvalue;
if(ValueType == "int")
{
int Strvalueint;
Strvalueint = input->getValue().toInt();
if((Strvalueint<MinIndex)||(Strvalueint>MaxIndex))
{
qDebug() << QString("Out of range(%1,%2)!").arg(MinIndex).arg(MaxIndex);
}
else
{
Strvalue=QString("%1").arg(Strvalueint);
model->setData(index, Strvalue, Qt::DisplayRole);
}
}
else
{
float Strvaluefloat;
Strvaluefloat = input->getValue().toFloat();
if((Strvaluefloat<MinIndex)||(Strvaluefloat>MaxIndex))
{
qDebug() << QString("Out of range(%1,%2)!").arg(MinIndex).arg(MaxIndex);
}
else
{
Strvalue=QString::number(Strvaluefloat, 'f', 3);
model->setData(index, Strvalue, Qt::DisplayRole);
}
}
}
}
}
else
{
QItemDelegate::setModelData(editor, model, index);
}
}
void ParEditDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if( index.column() == 1 )
{
QString ValueType=index.model()->index(index.row(),index.column()+4,index.parent()).data().toString();
if(ValueType=="bool")
{
bool data = index.data().toBool();
QStyleOptionButton checkBoxStyle; // QStyleOptionButton类用于描述绘制按钮的参数。
// 设置具体的绘制参数
checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
checkBoxStyle.state |= QStyle::State_Enabled;
checkBoxStyle.rect = option.rect;
//checkBoxStyle.iconSize = QSize(25, 25);
// checkBoxStyle.rect.setHeight(30);
// checkBoxStyle.rect.setWidth(30);
checkBoxStyle.rect.setX(option.rect.x() + option.rect.width() / 2 - 15); //勾选框在中间
//checkBoxStyle.rect.setY(option.rect.y() + option.rect.height() / 2 - 10); //勾选框在中间
// 根据参数绘制组件
QCheckBox checkBox;
QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxStyle, painter, &checkBox);
//QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);
}
else
{
QItemDelegate::paint(painter, option, index);
}
}
else
{
QItemDelegate::paint(painter, option, index);
}
}
bool ParEditDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
bool ret = true;
if( index.column() == 1 )
{
QString ValueType=index.model()->index(index.row(),index.column()+4,index.parent()).data().toString();
if(ValueType=="bool")
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
// 是鼠标按下事件,并且范围在具体数据项范围内
if( (event->type() == QEvent::MouseButtonPress) && option.rect.contains(mouseEvent->pos()) )
{
bool data = index.data(Qt::DisplayRole).toBool();
QString value;
if(data == false)
{
value = "1";
}
else
{
value = "0";
}
qDebug() << "set model data: " << !data;
qDebug() << model->setData(index, value, Qt::DisplayRole); // 重新设置模型中数据
}
}
else
{
ret = QItemDelegate::editorEvent(event, model, option, index);
}
}
else
{
ret = QItemDelegate::editorEvent(event, model, option, index);
}
return ret;
}
自己设计的数字输入键盘
#ifndef PARAMETERINPUT_H
#define PARAMETERINPUT_H
#include <QDialog>
#include <QLineEdit>
#include <QButtonGroup>
#include "components.h"
namespace Ui {
class ParameterInput;
}
enum ParaDataType {
dataInt = 0, //把输入处理成数值,比较上下限(如果已设定),调用端自己去根据需求获取整或浮点
dataFloat, //把输入处理成数值,比较上下限(如果已设定),调用端自己去根据需求获取整或浮点
dataString //把输入处理成字符,不限定范围
};
class ParameterInput : public QDialog {
Q_OBJECT
public:
explicit ParameterInput(QWidget *parent = 0, bool dotenable = false, bool signable = false, bool stepable = false);
~ParameterInput();
void setStepEnable(bool en);
void setTitleText(const QString &);
void setInitValue(QString unit, int value, int step = 0, int stop = 0);
void setInitValue(QString unit, float value, float step = 0, float stop = 0);
void setInitValue(QString value);
void setUnit(QString unit);
void setMinMax(float, float);
bool getStepEn(void);
QString getValue(void);//返回字符串,调用端自己去根据需求获取整或浮点
QString getStep(void); //返回字符串,调用端自己去根据需求获取整或浮点
QString getStop(void); //返回字符串,调用端自己去根据需求获取整或浮点
signals:
private slots:
void on_Input_StepEN_toggled(bool checked);
void on_InputASCII(QAbstractButton *);
protected:
bool eventFilter(QObject *obj, QEvent *e);
private:
Ui::ParameterInput *ui;
QButtonGroup btngroup;
QLineEdit *curr_edit;
QString m_title;
QString m_Unit;
QString m_value;
QString m_step;
QString m_stop;
bool m_stepable;
bool m_stepEn;
bool m_valueClear;
bool m_stepClear;
bool m_stopClear;
ParaDataType m_dataType;
bool checkminmax;
float v_min;
float v_max;
void submitInputNumber(QString &data, QString &input, bool step = false);
void updateOKButton(void);
};
#endif // PARAMETERINPUT_H
#include "parameterinput.h"
#include "ui_parameterinput.h"
#include <QDebug>
#include <math.h>
#include <QDesktopWidget>
ParameterInput::ParameterInput(QWidget *parent, bool dotenable, bool signable, bool stepable) :
QDialog(parent),
ui(new Ui::ParameterInput)
{
ui->setupUi(this);
Qt::WindowFlags flags = windowFlags();
setWindowFlags(flags | Qt::FramelessWindowHint | Qt::MSWindowsFixedSizeDialogHint| Qt::Tool);
if(stepable == false)
{
ui->Input_StepEN->setEnabled(false);
ui->Input_StepEN->setVisible(false);
ui->Input_Step->setEnabled(false);
ui->Input_Step->setVisible(false);
ui->Input_Stop->setEnabled(false);
ui->Input_Stop->setVisible(false);
ui->label_step->setVisible(false);
ui->label_stop->setVisible(false);
}
m_stepable = stepable;
m_stepEn = false;
if(dotenable == false)
{
ui->Input_dot->setEnabled(false);
}
if(signable == false)
{
ui->Input_sign->setEnabled(false);
}
btngroup.addButton(ui->Input_0,0);
btngroup.addButton(ui->Input_1,1);
btngroup.addButton(ui->Input_2,2);
btngroup.addButton(ui->Input_3,3);
btngroup.addButton(ui->Input_4,4);
btngroup.addButton(ui->Input_5,5);
btngroup.addButton(ui->Input_6,6);
btngroup.addButton(ui->Input_7,7);
btngroup.addButton(ui->Input_8,8);
btngroup.addButton(ui->Input_9,9);
btngroup.addButton(ui->Input_C,10);
btngroup.addButton(ui->Input_dot,11);
btngroup.addButton(ui->Input_sign,12);
btngroup.addButton(ui->Input_Del,13);
curr_edit = ui->Input_Start;
m_dataType = dataString;
checkminmax = false;
connect(&btngroup,QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),this,(&ParameterInput::on_InputASCII));
ui->Input_Start->installEventFilter(this);
ui->Input_Step->installEventFilter(this);
ui->Input_Stop->installEventFilter(this);
//ui->Input_Start->setFocus();
}
ParameterInput::~ParameterInput()
{
delete ui;
//qDebug()<<"parameter exit";
}
bool ParameterInput::eventFilter(QObject *obj, QEvent *e)
{
// if(obj == ui->lineEdit && e->type() == QEvent::MouseButtonPress)
// {
// QMouseEvent *me = (QMouseEvent*)e;
// if(me->button() == Qt::LeftButton)
// {
// }
// }
if(e->type() == QEvent::MouseButtonPress)
{
if(obj == ui->Input_Start)
curr_edit = ui->Input_Start;
else if(obj == ui->Input_Step)
curr_edit = ui->Input_Step;
else if(obj == ui->Input_Stop)
curr_edit = ui->Input_Stop;
// if(curr_edit != nullptr)
// curr_edit->selectAll();
}
return QDialog::eventFilter(obj,e);
}
void ParameterInput::setStepEnable(bool en)
{
// ui->Input_StepEN->setEnabled(en);
// ui->Input_StepEN->setVisible(en);
if(m_stepable)
{
ui->Input_StepEN->setChecked(en);
ui->Input_Step->setEnabled(en);
ui->Input_Stop->setEnabled(en);
m_stepEn = en;
}
}
void ParameterInput::setTitleText(const QString &title)
{
m_title = title;
if(checkminmax)
ui->labelTitle->setText(m_title + QString(" (%1 ~ %2)").arg(v_min).arg(v_max));
else
ui->labelTitle->setText(m_title);
}
void ParameterInput::setInitValue(QString unit, int value, int step, int stop)
{
m_dataType = dataInt;
m_value = QString::number(value);
m_step = QString::number(step);
m_stop = QString::number(stop);
if(!unit.isEmpty())
m_Unit = " " + unit;
else
m_Unit = "";
ui->Input_Start->setText(m_value + m_Unit);
ui->Input_Start->setSelection(0, m_value.length());
ui->Input_Step->setText(m_step + m_Unit);
ui->Input_Step->setSelection(0, m_step.length());
ui->Input_Stop->setText(m_stop + m_Unit);
ui->Input_Stop->setSelection(0, m_stop.length());
m_valueClear = true;
m_stepClear = true;
m_stopClear = true;
}
void ParameterInput::setInitValue(QString unit, float value, float step, float stop)
{
m_dataType = dataFloat;
m_value = QString::number(value);
m_step = QString::number(step);
m_stop = QString::number(stop);
if(!unit.isEmpty())
m_Unit = " " + unit;
else
m_Unit = "";
ui->Input_Start->setText(m_value + m_Unit);
ui->Input_Start->setSelection(0, m_value.length());
ui->Input_Step->setText(m_step + m_Unit);
ui->Input_Step->setSelection(0, m_step.length());
ui->Input_Stop->setText(m_stop + m_Unit);
ui->Input_Stop->setSelection(0, m_stop.length());
m_valueClear = true;
m_stepClear = true;
m_stopClear = true;
}
void ParameterInput::setInitValue(QString value)
{
m_dataType = dataString;
m_value = value;
ui->Input_Start->setText(m_value);
ui->Input_Start->setSelection(0, m_value.length());
m_valueClear = true;
}
void ParameterInput::setUnit(QString unit)
{
if(!unit.isEmpty())
m_Unit = " " + unit;
else
m_Unit = "";
}
void ParameterInput::setMinMax(float min, float max)
{
checkminmax = true;
if(max < min)
max = min;
v_min = min;
v_max = max;
ui->labelTitle->setText(m_title + QString(" (%1 ~ %2)").arg(v_min).arg(v_max));
}
bool ParameterInput::getStepEn(void)
{
return ui->Input_StepEN->checkState();
}
QString ParameterInput::getValue(void)
{
return m_value;
}
QString ParameterInput::getStep(void)
{
return m_step;
}
QString ParameterInput::getStop(void)
{
return m_stop;
}
void ParameterInput::on_Input_StepEN_toggled(bool checked)
{
if(checked)
{
ui->Input_Step->setEnabled(true);
ui->Input_Stop->setEnabled(true);
}
else
{
ui->Input_Step->setEnabled(false);
ui->Input_Stop->setEnabled(false);
}
m_stepEn = checked;
}
void ParameterInput::on_InputASCII(QAbstractButton *btn)
{
QString text = (static_cast <CPushButton *> (btn))->text();
//CPushButton *b1 = static_cast< CPushButton *> (btn);
//QString text = b1->text();
if(curr_edit == ui->Input_Start)
{
if(m_valueClear)
{
m_value = "";
m_valueClear = false;
}
submitInputNumber(m_value,text);
ui->Input_Start->setText(m_value + m_Unit);
}
else if(curr_edit == ui->Input_Step)
{
if(m_stepClear)
{
m_step = "";
m_stepClear = false;
}
submitInputNumber(m_step,text,true);
ui->Input_Step->setText(m_step + m_Unit);
}
else if(curr_edit == ui->Input_Stop)
{
if(m_stopClear)
{
m_stop = "";
m_stopClear = false;
}
submitInputNumber(m_stop,text);
ui->Input_Stop->setText(m_stop + m_Unit);
}
updateOKButton();
}
#define InputMaxLen_Number 10
#define InputMaxLen_Ascii 16
void ParameterInput::submitInputNumber(QString &data, QString &input, bool step)
{
float fvalue;
if(input == "C")
{
data = "";
//disp->setText(data);
return;
}
else if(input == "Del")
{
if(data.length() != 0)
{
data = data.left(data.length() - 1);
}
return;
}
if(m_dataType == dataString)
{
if(data.length() >= InputMaxLen_Ascii)
return;
if(input == "+/-")
return;
else
data = data + input;
//disp->setText(data);
return;
}
else
{
if(data.length() >= InputMaxLen_Number)
return;
}
if(input == ".")
{
if(data == "")
data = "0.";
else if(data.indexOf(".") < 0)
data = data + ".";
return;
}
else if(input == "+/-")
{
if(step == false)
{
if(data.length() == 0)
{
if((checkminmax==true)&&(v_min < 0))
data = "-";
}
else if(data.at(0) == '-')
{
if((checkminmax==true)&&(v_max > 0))
data = data.right(data.length()-1);
}
else
{
if((checkminmax==true)&&(v_min < 0))
data = "-" + data;
}
}
return;
}
else if(input == "0")
{
if(data == "0")
return;
}
else if((input > "0")&&(input <= "9"))
{
if(data == "0")
data = "";
}
data = data + input;
fvalue = data.toFloat();
if(checkminmax)
{
if(step)
{
float sub = v_max - v_min;
if(fabs(fvalue - sub) < 0.00001f)
{
}
else if(fvalue > sub)
{
data = data.left(data.length()-1);
}
}
else
{
if(data.at(0) == '-')
{
if(fabs(fvalue - v_min) < 0.00001f)
{
}
else if(fvalue < v_min)
data = data.left(data.length()-1);
}
else
{
if(fabs(fvalue - v_min) < 0.00001f)
{
}
else if(fvalue > v_max)
data = data.left(data.length()-1);
}
}
}
//qDebug()<<"input"<<data;
}
void ParameterInput::updateOKButton(void)
{
bool checkok = true;
float ftemp;
float sub;
if(checkminmax == true)
{
ftemp = m_value.toFloat();
if((fabs(ftemp - v_min) < 0.00001f) || (fabs(ftemp - v_max) < 0.00001f) ) // it's equal to min or max
{
}
else if((ftemp > v_max) || (ftemp < v_min))
{
checkok = false;
}
if(m_stepEn == true)
{
ftemp = m_step.toFloat();
sub = v_max - v_min;
if(fabs(ftemp) < 0.001f)
{
checkok = false;
}
else if(fabs(ftemp - sub) < 0.00001f) // it's equal to min or max
{
}
else if(ftemp > sub)
{
checkok = false;
}
ftemp = m_stop.toFloat();
if((fabs(ftemp - v_min) < 0.00001f) || (fabs(ftemp - v_max) < 0.00001f) ) // it's equal to min or max
{
}
else if((ftemp > v_max) || (ftemp < v_min))
{
checkok = false;
}
}
}
//if(checkok)
ui->para_okbtn->setEnabled(checkok);
}