Created
February 22, 2019 08:46
-
-
Save czaux/b045940ba596cf8a78f823136e527120 to your computer and use it in GitHub Desktop.
QT Widget Subtype signalling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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