总结:首先需要获取属性名和属性类别,然后根据属性类别采用合适方法设置新的属性值,新的属性值需要设置到从obs source中导出的obs setting中,最后将新的obs setting应用到obs source中
具体api如下:
1、获取属性名和属性类别
// 获取属性名
const char * propertyName = obs_property_name(property);
// 获取属性类别
obs_property_type propertyType = obs_property_get_type(property);
2、获取obs settings
OBSData settings = obs_source_get_settings(source);
3、设置新的属性值
switch (propertyType) {
case OBS_PROPERTY_INVALID: return;
case OBS_PROPERTY_BOOL: BoolChanged(setting); break;
case OBS_PROPERTY_INT: IntChanged(setting); break;
case OBS_PROPERTY_FLOAT: FloatChanged(setting); break;
case OBS_PROPERTY_TEXT: TextChanged(setting); break;
case OBS_PROPERTY_LIST: ListChanged(setting); break;
case OBS_PROPERTY_BUTTON: ButtonClicked(); return;
case OBS_PROPERTY_COLOR:
if (!ColorChanged(setting))
return;
break;
case OBS_PROPERTY_FONT:
if (!FontChanged(setting))
return;
break;
case OBS_PROPERTY_PATH:
if (!PathChanged(setting))
return;
break;
case OBS_PROPERTY_EDITABLE_LIST: break;
case OBS_PROPERTY_FRAME_RATE:
if (!FrameRateChanged(widget, setting, view->settings))
return;
break;
}
void WidgetInfo::BoolChanged(const char *setting)
{
QCheckBox *checkbox = static_cast<QCheckBox*>(widget);
obs_data_set_bool(view->settings, setting,
checkbox->checkState() == Qt::Checked);
}
void WidgetInfo::IntChanged(const char *setting)
{
QSpinBox *spin = static_cast<QSpinBox*>(widget);
obs_data_set_int(view->settings, setting, spin->value());
}
void WidgetInfo::FloatChanged(const char *setting)
{
QDoubleSpinBox *spin = static_cast<QDoubleSpinBox*>(widget);
obs_data_set_double(view->settings, setting, spin->value());
}
void WidgetInfo::TextChanged(const char *setting)
{
obs_text_type type = obs_property_text_type(property);
if (type == OBS_TEXT_MULTILINE) {
QPlainTextEdit *edit = static_cast<QPlainTextEdit*>(widget);
obs_data_set_string(view->settings, setting,
QT_TO_UTF8(edit->toPlainText()));
return;
}
QLineEdit *edit = static_cast<QLineEdit*>(widget);
obs_data_set_string(view->settings, setting, QT_TO_UTF8(edit->text()));
}
bool WidgetInfo::PathChanged(const char *setting)
{
const char *desc = obs_property_description(property);
obs_path_type type = obs_property_path_type(property);
const char *filter = obs_property_path_filter(property);
const char *default_path = obs_property_path_default_path(property);
QString path;
if (type == OBS_PATH_DIRECTORY)
path = QFileDialog::getExistingDirectory(view,
QT_UTF8(desc), QT_UTF8(default_path),
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
else if (type == OBS_PATH_FILE)
path = QFileDialog::getOpenFileName(view,
QT_UTF8(desc), QT_UTF8(default_path),
QT_UTF8(filter));
else if (type == OBS_PATH_FILE_SAVE)
path = QFileDialog::getSaveFileName(view,
QT_UTF8(desc), QT_UTF8(default_path),
QT_UTF8(filter));
if (path.isEmpty())
return false;
QLineEdit *edit = static_cast<QLineEdit*>(widget);
edit->setText(path);
obs_data_set_string(view->settings, setting, QT_TO_UTF8(path));
return true;
}
void WidgetInfo::ListChanged(const char *setting)
{
QComboBox *combo = static_cast<QComboBox*>(widget);
obs_combo_format format = obs_property_list_format(property);
obs_combo_type type = obs_property_list_type(property);
QVariant data;
if (type == OBS_COMBO_TYPE_EDITABLE) {
data = combo->currentText().toUtf8();
} else {
int index = combo->currentIndex();
if (index != -1)
data = combo->itemData(index);
else
return;
}
switch (format) {
case OBS_COMBO_FORMAT_INVALID:
return;
case OBS_COMBO_FORMAT_INT:
obs_data_set_int(view->settings, setting,
data.value<long long>());
break;
case OBS_COMBO_FORMAT_FLOAT:
obs_data_set_double(view->settings, setting,
data.value<double>());
break;
case OBS_COMBO_FORMAT_STRING:
obs_data_set_string(view->settings, setting,
data.toByteArray().constData());
break;
}
}
bool WidgetInfo::ColorChanged(const char *setting)
{
const char *desc = obs_property_description(property);
long long val = obs_data_get_int(view->settings, setting);
QColor color = color_from_int(val);
QColorDialog::ColorDialogOptions options =
QColorDialog::ShowAlphaChannel;
/* The native dialog on OSX has all kinds of problems, like closing
* other open QDialogs on exit, and
* https://bugreports.qt-project.org/browse/QTBUG-34532
*/
#ifdef __APPLE__
options |= QColorDialog::DontUseNativeDialog;
#endif
color = QColorDialog::getColor(color, view, QT_UTF8(desc), options);
color.setAlpha(255);
if (!color.isValid())
return false;
QLabel *label = static_cast<QLabel*>(widget);
label->setText(color.name(QColor::HexArgb));
QPalette palette = QPalette(color);
label->setPalette(palette);
label->setStyleSheet(
QString("background-color :%1; color: %2;")
.arg(palette.color(QPalette::Window).name(QColor::HexArgb))
.arg(palette.color(QPalette::WindowText).name(QColor::HexArgb)));
obs_data_set_int(view->settings, setting, color_to_int(color));
return true;
}
bool WidgetInfo::FontChanged(const char *setting)
{
obs_data_t *font_obj = obs_data_get_obj(view->settings, setting);
bool success;
uint32_t flags;
QFont font;
QFontDialog::FontDialogOptions options;
#ifdef __APPLE__
options = QFontDialog::DontUseNativeDialog;
#endif
if (!font_obj) {
QFont initial;
font = QFontDialog::getFont(&success, initial, view, "Pick a Font", options);
} else {
MakeQFont(font_obj, font);
font = QFontDialog::getFont(&success, font, view, "Pick a Font", options);
obs_data_release(font_obj);
}
if (!success)
return false;
font_obj = obs_data_create();
obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
obs_data_set_int(font_obj, "size", font.pointSize());
flags = font.bold() ? OBS_FONT_BOLD : 0;
flags |= font.italic() ? OBS_FONT_ITALIC : 0;
flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
obs_data_set_int(font_obj, "flags", flags);
QLabel *label = static_cast<QLabel*>(widget);
QFont labelFont;
MakeQFont(font_obj, labelFont, true);
label->setFont(labelFont);
label->setText(QString("%1 %2").arg(font.family(), font.styleName()));
obs_data_set_obj(view->settings, setting, font_obj);
obs_data_release(font_obj);
return true;
}
void WidgetInfo::EditableListChanged()
{
const char *setting = obs_property_name(property);
QListWidget *list = reinterpret_cast<QListWidget*>(widget);
obs_data_array *array = obs_data_array_create();
for (int i = 0; i < list->count(); i++) {
QListWidgetItem *item = list->item(i);
obs_data_t *arrayItem = obs_data_create();
obs_data_set_string(arrayItem, "value",
QT_TO_UTF8(item->text()));
obs_data_set_bool(arrayItem, "selected",
item->isSelected());
obs_data_set_bool(arrayItem, "hidden",
item->isHidden());
obs_data_array_push_back(array, arrayItem);
obs_data_release(arrayItem);
}
obs_data_set_array(view->settings, setting, array);
obs_data_array_release(array);
ControlChanged();
}
void WidgetInfo::ButtonClicked()
{
if (obs_property_button_clicked(property, view->obj)) {
QMetaObject::invokeMethod(view, "RefreshProperties",
Qt::QueuedConnection);
}
}
4、应用修改后的obs settings
void obs_source_update(obs_source_t *source, obs_data_t *settings)