Qt表格中代理输入控件支持bool,QString,枚举,整型,浮点

自己设计的数据输入代理控件

#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);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值