LINUX.ORG.RU

Я, конечно, не настоящий сварщик, может у Qt-программистов принято нарушать инкапсуляию по любому поводу, но никаких кнопок в программном интерфейсе спинбокса нет, следовательно физически присутствовать они тоже не обязаны. Можно, например, унаследоваться от спинбокса, и в обработчике OnValueChanged определять, увеличилось значение или уменьшилось, и эмитить разные сигналы для разных случаев? Ну и потом фильтровать. Если я правильно понял, чего ты хочешь.

roof ★★
()

Вот пример как можно отличить по имени объекта, по указателю на объект, по свойству объекта. Вариантов много, зависит от того что тебе требуется.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->spinBox_1->installEventFilter(this);
    ui->spinBox_2->installEventFilter(this);

    ui->spinBox_1->setObjectName("SpinBoxName1");
    ui->spinBox_2->setObjectName("SpinBoxName2");

    ui->spinBox_1->setProperty("SpinNumber", 1);
    ui->spinBox_2->setProperty("SpinNumber", 2);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    QEvent::Type type = event->type();
    if (QEvent::MouseButtonPress == type || QEvent::MouseButtonRelease == type) {
        if (QEvent::MouseButtonPress == type) {
            qDebug() << "\tPress event:";
        } else if (QEvent::MouseButtonRelease == type) {
            qDebug() << "\tRelease event:";
        }

        //Check by pointer:
        if (obj == qobject_cast<QObject*>(ui->spinBox_1)) {
            qDebug() << "SpinBox1 by pointer";
        } else if (obj == qobject_cast<QObject*>(ui->spinBox_2)) {
            qDebug() << "SpinBox2 by pointer";
        }

        //Check by name:
        if (obj->objectName() == "SpinBoxName1") {
            qDebug() << "SpinBox1 by name";
        } else if (obj->objectName() == "SpinBoxName2") {
            qDebug() << "SpinBox2 by name";
        }

        switch (obj->property("SpinNumber").toInt())
        {
        case 1:
            qDebug() << "SpinBox1 by property";
            break;
        case 2:
            qDebug() << "SpinBox2 by property";
            break;
        }
    }

    return QMainWindow::eventFilter (obj, event);
}

V1KT0P ★★
()

Тебе выше правильно ответили, API не подразумевает доступа к кнопочкам, все, что ты накостыляешь, костылями и останется.

Можешь как-то попытаться играть от того, что QSpinBox наследует от QWidget. Переписать обработчик событий, как-то вычислять кнопку в нем. Можешь сделать листенер, по сигналу valueChanged сравнивающий значение с предыдущим, сохраненным у себя. Например, если увеличилось, то был нажат инкремент, если уменьшилось, то декремент.

Однако, повторюсь, все это жуткие костыли. Если тебе действительно нужен этот функционал, сделай лучше свой SpinBox, со своими event’ами. Получится и проще, и поддерживаемее.

Вообще говоря, не понял прикола делать все эти QStepType, step’ы, когда можно было бы просто принимать две функции (или одной доп. параметр передавать). Тогда можно было бы и обычный QSpinBox запилить просто с помощью [](auto& n){ n += 1; }, и все кастомные типы данных в спинбокс пихать было бы тривиально, и никаких хаков для вычисления кнопок тем более не надо было бы. Но это уже пусть на совести разработчиков Qt остается.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от V1KT0P

Твой код определяет не то, какую кнопку в спинбоксе нажали, а то, какой из спинбоксов нажали. Не говоря уже о том, что это в Qt принято делать через наследование с переопределением соответствующего обработчика событий.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Да, точно. Затупил и не так понял, вот так например можно в Qt 5.9 узнать какую кнопку нажали(при чем неважно активная она или нет в вопросе про это ничего не сказано =) ):

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QMouseEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->spinBox_1->installEventFilter(this);
    ui->spinBox_2->installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    QEvent::Type type = event->type();

    if (QEvent::MouseButtonPress == type || QEvent::MouseButtonRelease == type) {
        QSpinBox* spinBox = nullptr;
        QString spinBoxName;
        QString mouseEventName;
        QString buttonName;

        if (obj == qobject_cast<QObject*>(ui->spinBox_1)) {
            spinBox = ui->spinBox_1;
            spinBoxName = "SpinBox1";
        }

        if (obj == qobject_cast<QObject*>(ui->spinBox_2)) {
            spinBox = ui->spinBox_2;
            spinBoxName = "SpinBox2";
        }

        if (QEvent::MouseButtonPress == type) {
            mouseEventName = "Press";
        } else if (QEvent::MouseButtonRelease == type) {
            mouseEventName = "Release";
        }

        if (spinBox != nullptr) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            QStyleOptionSpinBox option;
            option.initFrom(spinBox);
            QStyle::SubControl control = spinBox->style()->hitTestComplexControl(QStyle::CC_SpinBox, &option, mouseEvent->pos(), spinBox);
            if (control == QStyle::SC_SpinBoxUp) {
                buttonName = "Up";
            } else if (control == QStyle::SC_SpinBoxDown) {
                buttonName = "Down";
            } else if (QEvent::MouseButtonRelease == type) {
                buttonName = spinBox->property("buttonName").toString();
            }
            //Save name if mouse release happens out of button
            if (QEvent::MouseButtonPress == type) {
                spinBox->setProperty("buttonName", buttonName);
            }
            qDebug() << QString("%1: event %2 on button '%3'").arg(spinBoxName, mouseEventName, buttonName);
        }
    }

    return QMainWindow::eventFilter (obj, event);
}
V1KT0P ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.