Это будет выглядеть немного глупо, но, пожалуйста, следуйте за мной, если можете:
class Slider : public QSlider
{
Q_OBJECT
public:
Slider(QWidget *parent = nullptr);
void updateValue(int value) { setValue(value);}
int get() const { return value(); }
};
Проще говоря, я просто пытаюсь обновить значение пользовательского ползунка через контроллер (я знаю,Я могу сделать это со слотами, выполнив ui->horizontalSlider->setValue(int);
).
У меня есть Controller<T....> controller(t&...)
, который принимает произвольное количество классов и позволяет мне устанавливать их значения и получать их значения, например:
Controller<CustomSlider,CustomSpinBox,MyClass> controller(*ui->horizontalSlider,*ui->spinBox,myClass);
Итак, что я делаю со слотом, это скажу контроллеру обновить все значения следующим образом:
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
controller.setValues(value);
getValues();
}
getValues()
просто выводит на консоль, чтобы сообщить мне, что онидействительно все обновлено.
setValues(int)
вызывает функцию updateValue(int)
, которая вызывает функцию установки каждого класса.Это должно быть прямое обновление, однако всякий раз, когда я пытаюсь переместить ползунок, программа вылетает, и отладчик действительно не дает мне ничего полезного, кроме сбоя на qabstractslider.cpp
строка 531 Q_D(QAbstractSlider)
.Так что я не знаю, что с этим происходит.У кого-нибудь есть какие-либо предложения?
РЕДАКТИРОВАТЬ : Я должен отметить, что ui->horizontalSlider
был повышен до Slider
класса.
EDIT2 : Попросили сделать MVE, вот что я могу сделать:
#ifndef TESTCONTROLLER_HPP
#define TESTCONTROLLER_HPP
#include <QMainWindow>
#include "slider.hpp"
#include "spinbox.hpp"
#include "controller.hpp"
#include "myclass.hpp"
namespace Ui {
class TestController;
}
class TestController : public QMainWindow
{
Q_OBJECT
public:
explicit TestController(QWidget *parent = nullptr);
~TestController();
void getValues();
void print(const std::vector<int> &p);
private slots:
void on_horizontalSlider_valueChanged(int value);
void on_spinBox_valueChanged(int arg1);
private:
Ui::TestController *ui;
MyClass myClass;
Controller<Slider,SpinBox,myClass> controller;
};
#endif // TESTCONTROLLER_HPP
TestController.cpp:
#include "testcontroller.hpp"
#include "ui_testcontroller.h"
TestController::TestController(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::TestController),
controller(*ui->horizontalSlider,*ui->spinBox,myClass)
{
ui->setupUi(this);
}
TestController::~TestController()
{
delete ui;
}
void TestController::getValues()
{
std::vector<int> values;
controller.getValues(values);
print(values);
}
void TestController::print(const std::vector<int> &p)
{
for(const auto & e: p)
{
std::cout << e << " ";
}
std::cout << std::endl;
}
void TestController::on_horizontalSlider_valueChanged(int value)
{
controller.setValues(value);
getValues();
}
void TestController::on_spinBox_valueChanged(int arg1)
{
controller.setValues(arg1);
getValues();
}
controller.hpp:
#ifndef CONTROLLER_HPP
#define CONTROLLER_HPP
#include <functional>
#include <vector>
#include <iostream>
#include <utility>
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
Controller(std::tuple<Classes&...> tup) : objects(tup){}
void setValues(int value)
{
std::apply([&](auto&...x) { (x.updateValue(value),...);}, objects);
}
void getValues(std::vector<int> &values) const
{
std::apply([&](auto&...x) { (values.push_back(x.get()),...);}, objects);
}
std::tuple<Classes&...> getObjects() const
{
return objects;
}
private:
std::tuple<Classes&...> objects;
};
template<typename...ClassesL, typename...ClassesR>
auto operator+(const Controller<ClassesL...>& lhs, const Controller<ClassesR...>& rhs)
{
return Controller(std::tuple_cat(lhs.getObjects(),rhs.getObjects()));
}
template<typename...ClassesL, typename ClassesR>
auto operator+(const Controller<ClassesL...> &lhs, ClassesR rhs)
{
Controller<ClassesR> makeController(rhs);
return Controller(std::tuple_cat(lhs.getObjects(),makeController.getObjects()));
}
template<typename ClassesL, typename...ClassesR>
auto operator+(ClassesL lhs, const Controller<ClassesR...> &rhs)
{
Controller<ClassesL> makeController(lhs);
return Controller(std::tuple_cat(makeController.getObjects(),rhs.getObjects()));
}
#endif // CONTROLLER_HPP
При этом вам просто нужно скопировать класс Slider, а в файле .cpp вам нужно будет сделать Slider::Slider(QWidget *parent) : QSlider(parent)
.Класс Spin Box выглядит точно так же, как и ползунок, за исключением того, что он наследуется от QSpinBox
, тогда MyClass имеет свои собственные методы получения и установки, однако также должны быть включены updateValue
и get
.
Затем вам нужно добавить горизонтальный ползунок и спинбокс в дизайн, повысить оба ползунка до классов, которые я предоставил, и вы должны хорошо повторить проблему.