Skip to content

Instantly share code, notes, and snippets.

@czaux
Created February 22, 2019 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save czaux/b045940ba596cf8a78f823136e527120 to your computer and use it in GitHub Desktop.
Save czaux/b045940ba596cf8a78f823136e527120 to your computer and use it in GitHub Desktop.
QT Widget Subtype signalling
typedef std::map<QString, std::variant<int, double, bool, QString>> DataType;
DataType activeData;
template<class T, typename X>
void ConfigDialog::updateActiveData(T widget, X value) {
this->activeData[widget->objectName()] = value;
qDebug() << value;
}
ConfigDialog::ConfigDialog(QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *layout = new QVBoxLayout;
QUiLoader loader;
//Load from resource file
QFile file(":/ui/ConfigDialog.ui");
file.open(QIODevice::ReadOnly);
if(file.error() != QFile::NoError) {
qDebug() << file.error();
return;
}
QWidget *myDialog = qobject_cast<QWidget*>(loader.load(&file));
file.close();
layout->addWidget(myDialog);
setLayout(layout);
//This is dirty, but QT doesn't make its underlying class accessible without casting
//Any widgets not in this list will have to be added to be useable with the config.
QList<QWidget *> widgets = this->findChildren<QWidget *>();
//I am autolord, master of type inference. Requires C++14
auto connector = [this] (auto _widget, auto _signal) {
this->connect(_widget, _signal, this, [this, _widget] ( auto _value ) {
this->updateActiveData(_widget, _value);
});
};
auto editconnector = [this] (auto _widget, auto _signal) {
this->connect(_widget, _signal, this, [this, _widget] () {
this->updateActiveData(_widget, _widget->toPlainText());
});
};
for(QWidget * widget : widgets ) {
//Every widget for configs must have isconfigparameter in its properties.
if(widget->property("isconfigparameter").toBool()) {
if(auto _w = qobject_cast<QSlider *>(widget)) connector(_w, &QSlider::valueChanged);
if(auto _w = qobject_cast<QLineEdit *>(widget)) connector(_w, &QLineEdit::textChanged);
if(auto _w = qobject_cast<QCheckBox *>(widget)) connector(_w, &QCheckBox::toggled);
//SpinBox has QString and int overloads. QT 5.7 has qOverload to choose one type.
if(auto _w = qobject_cast<QSpinBox *>(widget)) connector(_w, qOverload<int>(&QSpinBox::valueChanged));
if(auto _w = qobject_cast<QDial *>(widget)) connector(_w, &QDial::valueChanged);
if(auto _w = qobject_cast<QProgressBar *>( widget)) connector(_w, &QProgressBar::valueChanged);
if(auto _w = qobject_cast<QDoubleSpinBox *>( widget)) connector(_w, qOverload<double>(&QDoubleSpinBox::valueChanged));
if(auto _w = qobject_cast<QComboBox *>( widget)) connector(_w, qOverload<const QString &>(&QComboBox::currentIndexChanged));
//TextEdits are special in that their signal returns void, because why have conformance.
if(auto _w = qobject_cast<QTextEdit *>( widget)) editconnector(_w, &QTextEdit::textChanged);
if(auto _w = qobject_cast<QPlainTextEdit *>( widget)) editconnector(_w, &QPlainTextEdit::textChanged);
}
}
//Only care about the QButtonGroup, not individual Radio Buttons.
QList<QButtonGroup *> buttongroups = this->findChildren<QButtonGroup *>();
for(QButtonGroup * group : buttongroups ) {
this->connect(group, qOverload<QAbstractButton *, bool>(&QButtonGroup::buttonToggled), this, [this, group] (QAbstractButton * b, bool value) {
if(value) this->updateActiveData(group, b->text());
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment