这似乎有点愚蠢,但如果可以的话,请关注我
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)
,该函数调用每个类的setter函数。这应该是一个直接的更新,但是,每当我尝试移动滑块时,程序都会崩溃,并且调试器除了在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具有自己的getter和setter,但是还必须包括updateValue
和get
。
然后,您需要在设计中添加一个水平滑块和一个旋转框,将这两个滑块都升级到我提供的类中,并且应该很好地复制问题。