Browse Source

Merge pull request #8689 from gxalpha/no-more-signal-slot-macro

UI: SIGNAL and SLOT macros begone!
Lain 2 years ago
parent
commit
346b93c9c4

+ 28 - 57
UI/adv-audio-control.cpp

@@ -16,6 +16,8 @@
 
 #define MIN_DB -96.0
 #define MAX_DB 26.0
+static inline void setMixer(obs_source_t *source, const int mixerIdx,
+			    const bool checked);
 
 OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
 	: source(source_)
@@ -223,34 +225,33 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
 	mixerContainer->layout()->addWidget(mixer6);
 	mixerContainer->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
 
-	QWidget::connect(volume, SIGNAL(valueChanged(double)), this,
-			 SLOT(volumeChanged(double)));
-	QWidget::connect(percent, SIGNAL(valueChanged(int)), this,
-			 SLOT(percentChanged(int)));
-	QWidget::connect(forceMono, SIGNAL(clicked(bool)), this,
-			 SLOT(downmixMonoChanged(bool)));
-	QWidget::connect(balance, SIGNAL(valueChanged(int)), this,
-			 SLOT(balanceChanged(int)));
-	QWidget::connect(balance, SIGNAL(doubleClicked()), this,
-			 SLOT(ResetBalance()));
-	QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this,
-			 SLOT(syncOffsetChanged(int)));
+	connect(volume, &QDoubleSpinBox::valueChanged, this,
+		&OBSAdvAudioCtrl::volumeChanged);
+	connect(percent, &QSpinBox::valueChanged, this,
+		&OBSAdvAudioCtrl::percentChanged);
+	connect(forceMono, &QCheckBox::clicked, this,
+		&OBSAdvAudioCtrl::downmixMonoChanged);
+	connect(balance, &BalanceSlider::valueChanged, this,
+		&OBSAdvAudioCtrl::balanceChanged);
+	connect(balance, &BalanceSlider::doubleClicked, this,
+		&OBSAdvAudioCtrl::ResetBalance);
+	connect(syncOffset, &QSpinBox::valueChanged, this,
+		&OBSAdvAudioCtrl::syncOffsetChanged);
 	if (obs_audio_monitoring_available())
-		QWidget::connect(monitoringType,
-				 SIGNAL(currentIndexChanged(int)), this,
-				 SLOT(monitoringTypeChanged(int)));
-	QWidget::connect(mixer1, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer1Changed(bool)));
-	QWidget::connect(mixer2, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer2Changed(bool)));
-	QWidget::connect(mixer3, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer3Changed(bool)));
-	QWidget::connect(mixer4, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer4Changed(bool)));
-	QWidget::connect(mixer5, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer5Changed(bool)));
-	QWidget::connect(mixer6, SIGNAL(clicked(bool)), this,
-			 SLOT(mixer6Changed(bool)));
+		connect(monitoringType, &QComboBox::currentIndexChanged, this,
+			&OBSAdvAudioCtrl::monitoringTypeChanged);
+
+	auto connectMixer = [this](QCheckBox *mixer, int num) {
+		connect(mixer, &QCheckBox::clicked, [this, num](bool checked) {
+			setMixer(source, num, checked);
+		});
+	};
+	connectMixer(mixer1, 0);
+	connectMixer(mixer2, 1);
+	connectMixer(mixer3, 2);
+	connectMixer(mixer4, 3);
+	connectMixer(mixer5, 4);
+	connectMixer(mixer6, 5);
 
 	setObjectName(sourceName);
 }
@@ -645,36 +646,6 @@ static inline void setMixer(obs_source_t *source, const int mixerIdx,
 		uuid);
 }
 
-void OBSAdvAudioCtrl::mixer1Changed(bool checked)
-{
-	setMixer(source, 0, checked);
-}
-
-void OBSAdvAudioCtrl::mixer2Changed(bool checked)
-{
-	setMixer(source, 1, checked);
-}
-
-void OBSAdvAudioCtrl::mixer3Changed(bool checked)
-{
-	setMixer(source, 2, checked);
-}
-
-void OBSAdvAudioCtrl::mixer4Changed(bool checked)
-{
-	setMixer(source, 3, checked);
-}
-
-void OBSAdvAudioCtrl::mixer5Changed(bool checked)
-{
-	setMixer(source, 4, checked);
-}
-
-void OBSAdvAudioCtrl::mixer6Changed(bool checked)
-{
-	setMixer(source, 5, checked);
-}
-
 void OBSAdvAudioCtrl::SetVolumeWidget(VolumeType type)
 {
 	switch (type) {

+ 0 - 6
UI/adv-audio-control.hpp

@@ -93,11 +93,5 @@ public slots:
 	void balanceChanged(int val);
 	void syncOffsetChanged(int milliseconds);
 	void monitoringTypeChanged(int index);
-	void mixer1Changed(bool checked);
-	void mixer2Changed(bool checked);
-	void mixer3Changed(bool checked);
-	void mixer4Changed(bool checked);
-	void mixer5Changed(bool checked);
-	void mixer6Changed(bool checked);
 	void ResetBalance();
 };

+ 4 - 4
UI/auth-youtube.cpp

@@ -355,10 +355,10 @@ void YoutubeChatDock::SetWidget(QCefWidget *widget_)
 	widget->setLayout(layout);
 	setWidget(widget);
 
-	QWidget::connect(lineEdit, SIGNAL(returnPressed()), this,
-			 SLOT(SendChatMessage()));
-	QWidget::connect(sendButton, SIGNAL(pressed()), this,
-			 SLOT(SendChatMessage()));
+	QWidget::connect(lineEdit, &LineEditAutoResize::returnPressed, this,
+			 &YoutubeChatDock::SendChatMessage);
+	QWidget::connect(sendButton, &QPushButton::pressed, this,
+			 &YoutubeChatDock::SendChatMessage);
 
 	cefWidget.reset(widget_);
 }

+ 3 - 7
UI/double-slider.cpp

@@ -4,8 +4,9 @@
 
 DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent)
 {
-	connect(this, SIGNAL(valueChanged(int)), this,
-		SLOT(intValChanged(int)));
+	connect(this, &DoubleSlider::valueChanged, [this](int val) {
+		emit doubleValChanged((minVal / minStep + val) * minStep);
+	});
 }
 
 void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
@@ -24,11 +25,6 @@ void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
 	setDoubleVal(val);
 }
 
-void DoubleSlider::intValChanged(int val)
-{
-	emit doubleValChanged((minVal / minStep + val) * minStep);
-}
-
 void DoubleSlider::setDoubleVal(double val)
 {
 	setValue(lround((val - minVal) / minStep));

+ 0 - 1
UI/double-slider.hpp

@@ -18,6 +18,5 @@ signals:
 	void doubleValChanged(double val);
 
 public slots:
-	void intValChanged(int val);
 	void setDoubleVal(double val);
 };

+ 6 - 6
UI/frontend-plugins/aja-output-ui/AJAOutputUI.cpp

@@ -73,8 +73,8 @@ void AJAOutputUI::SetupPropertiesView()
 	ui->propertiesLayout->addWidget(propertiesView);
 	obs_data_release(settings);
 
-	connect(propertiesView, SIGNAL(Changed()), this,
-		SLOT(PropertiesChanged()));
+	connect(propertiesView, &OBSPropertiesView::Changed, this,
+		&AJAOutputUI::PropertiesChanged);
 }
 
 void AJAOutputUI::SaveSettings(const char *filename, obs_data_t *settings)
@@ -130,8 +130,8 @@ void AJAOutputUI::SetupPreviewPropertiesView()
 	ui->previewPropertiesLayout->addWidget(previewPropertiesView);
 	obs_data_release(settings);
 
-	connect(previewPropertiesView, SIGNAL(Changed()), this,
-		SLOT(PreviewPropertiesChanged()));
+	connect(previewPropertiesView, &OBSPropertiesView::Changed, this,
+		&AJAOutputUI::PreviewPropertiesChanged);
 }
 
 void AJAOutputUI::on_outputButton_clicked()
@@ -269,6 +269,6 @@ void AJAOutputUI::SetupMiscPropertiesView()
 
 	ui->miscPropertiesLayout->addWidget(miscPropertiesView);
 	obs_data_release(settings);
-	connect(miscPropertiesView, SIGNAL(Changed()), this,
-		SLOT(MiscPropertiesChanged()));
+	connect(miscPropertiesView, &OBSPropertiesView::Changed, this,
+		&AJAOutputUI::MiscPropertiesChanged);
 }

+ 4 - 4
UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp

@@ -44,8 +44,8 @@ void DecklinkOutputUI::SetupPropertiesView()
 	ui->propertiesLayout->addWidget(propertiesView);
 	obs_data_release(settings);
 
-	connect(propertiesView, SIGNAL(Changed()), this,
-		SLOT(PropertiesChanged()));
+	connect(propertiesView, &OBSPropertiesView::Changed, this,
+		&DecklinkOutputUI::PropertiesChanged);
 }
 
 void DecklinkOutputUI::SaveSettings()
@@ -81,8 +81,8 @@ void DecklinkOutputUI::SetupPreviewPropertiesView()
 	ui->previewPropertiesLayout->addWidget(previewPropertiesView);
 	obs_data_release(settings);
 
-	connect(previewPropertiesView, SIGNAL(Changed()), this,
-		SLOT(PreviewPropertiesChanged()));
+	connect(previewPropertiesView, &OBSPropertiesView::Changed, this,
+		&DecklinkOutputUI::PreviewPropertiesChanged);
 }
 
 void DecklinkOutputUI::SavePreviewSettings()

+ 15 - 15
UI/frontend-plugins/frontend-tools/output-timer.cpp

@@ -20,12 +20,12 @@ OutputTimer::OutputTimer(QWidget *parent)
 
 	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
 
-	QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
-			 SLOT(StreamingTimerButton()));
-	QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,
-			 SLOT(RecordingTimerButton()));
+	QObject::connect(ui->outputTimerStream, &QPushButton::clicked, this,
+			 &OutputTimer::StreamingTimerButton);
+	QObject::connect(ui->outputTimerRecord, &QPushButton::clicked, this,
+			 &OutputTimer::RecordingTimerButton);
 	QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close),
-			 SIGNAL(clicked()), this, SLOT(hide()));
+			 &QPushButton::clicked, this, &OutputTimer::hide);
 
 	streamingTimer = new QTimer(this);
 	streamingTimerDisplay = new QTimer(this);
@@ -86,11 +86,11 @@ void OutputTimer::StreamTimerStart()
 	streamingTimer->setInterval(total);
 	streamingTimer->setSingleShot(true);
 
-	QObject::connect(streamingTimer, SIGNAL(timeout()),
-			 SLOT(EventStopStreaming()));
+	QObject::connect(streamingTimer, &QTimer::timeout, this,
+			 &OutputTimer::EventStopStreaming);
 
-	QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this,
-			 SLOT(UpdateStreamTimerDisplay()));
+	QObject::connect(streamingTimerDisplay, &QTimer::timeout, this,
+			 &OutputTimer::UpdateStreamTimerDisplay);
 
 	streamingTimer->start();
 	streamingTimerDisplay->start(1000);
@@ -120,11 +120,11 @@ void OutputTimer::RecordTimerStart()
 	recordingTimer->setInterval(total);
 	recordingTimer->setSingleShot(true);
 
-	QObject::connect(recordingTimer, SIGNAL(timeout()),
-			 SLOT(EventStopRecording()));
+	QObject::connect(recordingTimer, &QTimer::timeout, this,
+			 &OutputTimer::EventStopRecording);
 
-	QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this,
-			 SLOT(UpdateRecordTimerDisplay()));
+	QObject::connect(recordingTimerDisplay, &QTimer::timeout, this,
+			 &OutputTimer::UpdateRecordTimerDisplay);
 
 	recordingTimer->start();
 	recordingTimerDisplay->start(1000);
@@ -229,10 +229,10 @@ void OutputTimer::ShowHideDialog()
 {
 	if (!isVisible()) {
 		setVisible(true);
-		QTimer::singleShot(250, this, SLOT(show()));
+		QTimer::singleShot(250, this, &OutputTimer::show);
 	} else {
 		setVisible(false);
-		QTimer::singleShot(250, this, SLOT(hide()));
+		QTimer::singleShot(250, this, &OutputTimer::hide);
 	}
 }
 

+ 4 - 4
UI/frontend-plugins/frontend-tools/scripts.cpp

@@ -420,17 +420,17 @@ void ScriptsTool::on_scripts_customContextMenuRequested(const QPoint &pos)
 
 	obs_frontend_push_ui_translation(obs_module_get_string);
 
-	popup.addAction(tr("Add"), this, SLOT(on_addScripts_clicked()));
+	popup.addAction(tr("Add"), this, &ScriptsTool::on_addScripts_clicked);
 
 	if (item) {
 		popup.addSeparator();
 		popup.addAction(obs_module_text("Reload"), this,
-				SLOT(on_reloadScripts_clicked()));
+				&ScriptsTool::on_reloadScripts_clicked);
 		popup.addAction(obs_module_text("OpenFileLocation"), this,
-				SLOT(OpenScriptParentDirectory()));
+				&ScriptsTool::OpenScriptParentDirectory);
 		popup.addSeparator();
 		popup.addAction(tr("Remove"), this,
-				SLOT(on_removeScripts_clicked()));
+				&ScriptsTool::on_removeScripts_clicked);
 	}
 	obs_frontend_pop_ui_translation();
 

+ 4 - 3
UI/lineedit-autoresize.cpp

@@ -2,10 +2,11 @@
 
 LineEditAutoResize::LineEditAutoResize()
 {
-	connect(this, SIGNAL(textChanged()), this, SLOT(checkTextLength()));
+	connect(this, &LineEditAutoResize::textChanged, this,
+		&LineEditAutoResize::checkTextLength);
 	connect(document()->documentLayout(),
-		SIGNAL(documentSizeChanged(const QSizeF &)), this,
-		SLOT(resizeVertically(const QSizeF &)));
+		&QAbstractTextDocumentLayout::documentSizeChanged, this,
+		&LineEditAutoResize::resizeVertically);
 }
 
 void LineEditAutoResize::checkTextLength()

+ 20 - 18
UI/media-controls.cpp

@@ -54,17 +54,18 @@ MediaControls::MediaControls(QWidget *parent)
 	ui->stopButton->setProperty("themeID", "stopIcon");
 	setFocusPolicy(Qt::StrongFocus);
 
-	connect(&mediaTimer, SIGNAL(timeout()), this,
-		SLOT(SetSliderPosition()));
-	connect(&seekTimer, SIGNAL(timeout()), this, SLOT(SeekTimerCallback()));
-	connect(ui->slider, SIGNAL(sliderPressed()), this,
-		SLOT(MediaSliderClicked()));
-	connect(ui->slider, SIGNAL(mediaSliderHovered(int)), this,
-		SLOT(MediaSliderHovered(int)));
-	connect(ui->slider, SIGNAL(sliderReleased()), this,
-		SLOT(MediaSliderReleased()));
-	connect(ui->slider, SIGNAL(sliderMoved(int)), this,
-		SLOT(MediaSliderMoved(int)));
+	connect(&mediaTimer, &QTimer::timeout, this,
+		&MediaControls::SetSliderPosition);
+	connect(&seekTimer, &QTimer::timeout, this,
+		&MediaControls::SeekTimerCallback);
+	connect(ui->slider, &MediaSlider::sliderPressed, this,
+		&MediaControls::MediaSliderClicked);
+	connect(ui->slider, &MediaSlider::mediaSliderHovered, this,
+		&MediaControls::MediaSliderHovered);
+	connect(ui->slider, &MediaSlider::sliderReleased, this,
+		&MediaControls::MediaSliderReleased);
+	connect(ui->slider, &MediaSlider::sliderMoved, this,
+		&MediaControls::MediaSliderMoved);
 
 	countDownTimer = config_get_bool(App()->GlobalConfig(), "BasicWindow",
 					 "MediaControlsCountdownTimer");
@@ -72,27 +73,28 @@ MediaControls::MediaControls(QWidget *parent)
 	QAction *restartAction = new QAction(this);
 	restartAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
 	restartAction->setShortcut({Qt::Key_R});
-	connect(restartAction, SIGNAL(triggered()), this, SLOT(RestartMedia()));
+	connect(restartAction, &QAction::triggered, this,
+		&MediaControls::RestartMedia);
 	addAction(restartAction);
 
 	QAction *sliderFoward = new QAction(this);
 	sliderFoward->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-	connect(sliderFoward, SIGNAL(triggered()), this,
-		SLOT(MoveSliderFoward()));
+	connect(sliderFoward, &QAction::triggered, this,
+		&MediaControls::MoveSliderFoward);
 	sliderFoward->setShortcut({Qt::Key_Right});
 	addAction(sliderFoward);
 
 	QAction *sliderBack = new QAction(this);
 	sliderBack->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-	connect(sliderBack, SIGNAL(triggered()), this,
-		SLOT(MoveSliderBackwards()));
+	connect(sliderBack, &QAction::triggered, this,
+		&MediaControls::MoveSliderBackwards);
 	sliderBack->setShortcut({Qt::Key_Left});
 	addAction(sliderBack);
 
 	QAction *playPause = new QAction(this);
 	playPause->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-	connect(playPause, SIGNAL(triggered()), this,
-		SLOT(on_playPauseButton_clicked()));
+	connect(playPause, &QAction::triggered, this,
+		&MediaControls::on_playPauseButton_clicked);
 	playPause->setShortcut({Qt::Key_Space});
 	addAction(playPause);
 }

+ 3 - 3
UI/obs-app.cpp

@@ -1411,8 +1411,8 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store)
 	/* Handle SIGINT properly */
 	socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFd);
 	snInt = new QSocketNotifier(sigintFd[1], QSocketNotifier::Read, this);
-	connect(snInt, SIGNAL(activated(QSocketDescriptor)), this,
-		SLOT(ProcessSigInt()));
+	connect(snInt, &QSocketNotifier::activated, this,
+		&OBSApp::ProcessSigInt);
 #endif
 
 	sleepInhibitor = os_inhibit_sleep_create("OBS Video/audio");
@@ -1734,7 +1734,7 @@ bool OBSApp::OBSInit()
 	mainWindow = new OBSBasic();
 
 	mainWindow->setAttribute(Qt::WA_DeleteOnClose, true);
-	connect(mainWindow, SIGNAL(destroyed()), this, SLOT(quit()));
+	connect(mainWindow, &OBSBasic::destroyed, this, &OBSApp::quit);
 
 	mainWindow->OBSInit();
 

+ 41 - 40
UI/properties-view.cpp

@@ -262,13 +262,14 @@ void OBSPropertiesView::resizeEvent(QResizeEvent *event)
 	VScrollArea::resizeEvent(event);
 }
 
-QWidget *OBSPropertiesView::NewWidget(obs_property_t *prop, QWidget *widget,
-				      const char *signal)
+template<typename Sender, typename SenderParent, typename... Args>
+QWidget *OBSPropertiesView::NewWidget(obs_property_t *prop, Sender *widget,
+				      void (SenderParent::*signal)(Args...))
 {
 	const char *long_desc = obs_property_long_description(prop);
 
 	WidgetInfo *info = new WidgetInfo(this, prop, widget);
-	connect(widget, signal, info, SLOT(ControlChanged()));
+	QObject::connect(widget, signal, info, &WidgetInfo::ControlChanged);
 	children.emplace_back(info);
 
 	widget->setToolTip(QT_UTF8(long_desc));
@@ -283,7 +284,7 @@ QWidget *OBSPropertiesView::AddCheckbox(obs_property_t *prop)
 
 	QCheckBox *checkbox = new QCheckBox(QT_UTF8(desc));
 	checkbox->setCheckState(val ? Qt::Checked : Qt::Unchecked);
-	return NewWidget(prop, checkbox, SIGNAL(stateChanged(int)));
+	return NewWidget(prop, checkbox, &QCheckBox::stateChanged);
 }
 
 QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
@@ -298,7 +299,7 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
 		OBSPlainTextEdit *edit = new OBSPlainTextEdit(this, monospace);
 		edit->setPlainText(QT_UTF8(val));
 		edit->setTabStopDistance(40);
-		return NewWidget(prop, edit, SIGNAL(textChanged()));
+		return NewWidget(prop, edit, &OBSPlainTextEdit::textChanged);
 
 	} else if (type == OBS_TEXT_PASSWORD) {
 		QLayout *subLayout = new QHBoxLayout();
@@ -326,8 +327,8 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
 
 		edit->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 
-		connect(edit, SIGNAL(textEdited(const QString &)), info,
-			SLOT(ControlChanged()));
+		connect(edit, &QLineEdit::textEdited, info,
+			&WidgetInfo::ControlChanged);
 		return nullptr;
 	} else if (type == OBS_TEXT_INFO) {
 		QString desc = QT_UTF8(obs_property_description(prop));
@@ -380,7 +381,7 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout,
 	edit->setText(QT_UTF8(val));
 	edit->setToolTip(QT_UTF8(obs_property_long_description(prop)));
 
-	return NewWidget(prop, edit, SIGNAL(textEdited(const QString &)));
+	return NewWidget(prop, edit, &QLineEdit::textEdited);
 }
 
 void OBSPropertiesView::AddPath(obs_property_t *prop, QFormLayout *layout,
@@ -406,7 +407,8 @@ void OBSPropertiesView::AddPath(obs_property_t *prop, QFormLayout *layout,
 	subLayout->addWidget(button);
 
 	WidgetInfo *info = new WidgetInfo(this, prop, edit);
-	connect(button, SIGNAL(clicked()), info, SLOT(ControlChanged()));
+	connect(button, &QPushButton::clicked, info,
+		&WidgetInfo::ControlChanged);
 	children.emplace_back(info);
 
 	*label = new QLabel(QT_UTF8(obs_property_description(prop)));
@@ -450,13 +452,14 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout,
 		slider->setEnabled(obs_property_enabled(prop));
 		subLayout->addWidget(slider);
 
-		connect(slider, SIGNAL(valueChanged(int)), spin,
-			SLOT(setValue(int)));
-		connect(spin, SIGNAL(valueChanged(int)), slider,
-			SLOT(setValue(int)));
+		connect(slider, &QSlider::valueChanged, spin,
+			&QSpinBox::setValue);
+		connect(spin, &QSpinBox::valueChanged, slider,
+			&QSlider::setValue);
 	}
 
-	connect(spin, SIGNAL(valueChanged(int)), info, SLOT(ControlChanged()));
+	connect(spin, &QSpinBox::valueChanged, info,
+		&WidgetInfo::ControlChanged);
 
 	subLayout->addWidget(spin);
 
@@ -506,14 +509,14 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout,
 		slider->setOrientation(Qt::Horizontal);
 		subLayout->addWidget(slider);
 
-		connect(slider, SIGNAL(doubleValChanged(double)), spin,
-			SLOT(setValue(double)));
-		connect(spin, SIGNAL(valueChanged(double)), slider,
-			SLOT(setDoubleVal(double)));
+		connect(slider, &DoubleSlider::doubleValChanged, spin,
+			&QDoubleSpinBox::setValue);
+		connect(spin, &QDoubleSpinBox::valueChanged, slider,
+			&DoubleSlider::setDoubleVal);
 	}
 
-	connect(spin, SIGNAL(valueChanged(double)), info,
-		SLOT(ControlChanged()));
+	connect(spin, &QDoubleSpinBox::valueChanged, info,
+		&WidgetInfo::ControlChanged);
 
 	subLayout->addWidget(spin);
 
@@ -637,9 +640,8 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
 			WidgetInfo *info = new WidgetInfo(
 				this, prop, buttonGroup->buttons()[0]);
 			children.emplace_back(info);
-			connect(buttonGroup,
-				SIGNAL(buttonClicked(QAbstractButton *)), info,
-				SLOT(ControlChanged()));
+			connect(buttonGroup, &QButtonGroup::buttonClicked, info,
+				&WidgetInfo::ControlChanged);
 		}
 
 		QWidget *widget = new QWidget();
@@ -667,8 +669,7 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
 	}
 
 	if (type == OBS_COMBO_TYPE_EDITABLE)
-		return NewWidget(prop, combo,
-				 SIGNAL(editTextChanged(const QString &)));
+		return NewWidget(prop, combo, &QComboBox::editTextChanged);
 
 	if (idx != -1)
 		combo->setCurrentIndex(idx);
@@ -693,8 +694,8 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning)
 		  model->flags(model->index(idx, 0)) == Qt::NoItemFlags;
 
 	WidgetInfo *info = new WidgetInfo(this, prop, combo);
-	connect(combo, SIGNAL(currentIndexChanged(int)), info,
-		SLOT(ControlChanged()));
+	connect(combo, &QComboBox::currentIndexChanged, info,
+		&WidgetInfo::ControlChanged);
 	children.emplace_back(info);
 
 	/* trigger a settings update if the index was not found */
@@ -744,8 +745,8 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
 	WidgetInfo *info = new WidgetInfo(this, prop, list);
 
 	list->setDragDropMode(QAbstractItemView::InternalMove);
-	connect(list->model(), SIGNAL(rowsMoved()), info,
-		SLOT(EditListReordered()));
+	connect(list->model(), &QAbstractItemModel::rowsMoved,
+		[info]() { info->EditableListChanged(); });
 
 	QVBoxLayout *sideLayout = new QVBoxLayout();
 	NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -776,7 +777,7 @@ QWidget *OBSPropertiesView::AddButton(obs_property_t *prop)
 	QPushButton *button = new QPushButton(QT_UTF8(desc));
 	button->setProperty("themeID", "settingsButtons");
 	button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
-	return NewWidget(prop, button, SIGNAL(clicked()));
+	return NewWidget(prop, button, &QPushButton::clicked);
 }
 
 void OBSPropertiesView::AddColorInternal(obs_property_t *prop,
@@ -825,7 +826,8 @@ void OBSPropertiesView::AddColorInternal(obs_property_t *prop,
 	subLayout->addWidget(button);
 
 	WidgetInfo *info = new WidgetInfo(this, prop, colorLabel);
-	connect(button, SIGNAL(clicked()), info, SLOT(ControlChanged()));
+	connect(button, &QPushButton::clicked, info,
+		&WidgetInfo::ControlChanged);
 	children.emplace_back(info);
 
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
@@ -913,7 +915,8 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout,
 	subLayout->addWidget(button);
 
 	WidgetInfo *info = new WidgetInfo(this, prop, fontLabel);
-	connect(button, SIGNAL(clicked()), info, SLOT(ControlChanged()));
+	connect(button, &QPushButton::clicked, info,
+		&WidgetInfo::ControlChanged);
 	children.emplace_back(info);
 
 	label = new QLabel(QT_UTF8(obs_property_description(prop)));
@@ -1522,7 +1525,8 @@ void OBSPropertiesView::AddGroup(obs_property_t *prop, QFormLayout *layout)
 	children.emplace_back(info);
 
 	// Signals
-	connect(groupBox, SIGNAL(toggled(bool)), info, SLOT(ControlChanged()));
+	connect(groupBox, &QGroupBox::toggled, info,
+		&WidgetInfo::ControlChanged);
 }
 
 void OBSPropertiesView::AddProperty(obs_property_t *property,
@@ -1998,11 +2002,6 @@ void WidgetInfo::GroupChanged(const char *setting)
 						  : true);
 }
 
-void WidgetInfo::EditListReordered()
-{
-	EditableListChanged();
-}
-
 void WidgetInfo::EditableListChanged()
 {
 	const char *setting = obs_property_name(property);
@@ -2226,8 +2225,10 @@ public:
 		setLayout(mainLayout);
 		resize(QSize(400, 80));
 
-		connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-		connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+		connect(buttonBox, &QDialogButtonBox::accepted, this,
+			&EditableItemDialog::accept);
+		connect(buttonBox, &QDialogButtonBox::rejected, this,
+			&EditableItemDialog::reject);
 	}
 
 	inline QString GetText() const { return edit->text(); }

+ 3 - 3
UI/properties-view.hpp

@@ -79,7 +79,6 @@ public slots:
 	void EditListEdit();
 	void EditListUp();
 	void EditListDown();
-	void EditListReordered();
 };
 
 /* ------------------------------------------------------------------------- */
@@ -109,8 +108,9 @@ private:
 	QWidget *lastWidget = nullptr;
 	bool deferUpdate;
 
-	QWidget *NewWidget(obs_property_t *prop, QWidget *widget,
-			   const char *signal);
+	template<typename Sender, typename SenderParent, typename... Args>
+	QWidget *NewWidget(obs_property_t *prop, Sender *widget,
+			   void (SenderParent::*signal)(Args...));
 
 	QWidget *AddCheckbox(obs_property_t *prop);
 	QWidget *AddText(obs_property_t *prop, QFormLayout *layout,

+ 3 - 7
UI/visibility-item-widget.cpp

@@ -34,8 +34,9 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
 	setLayout(itemLayout);
 	setStyleSheet("background-color: rgba(255, 255, 255, 0);");
 
-	connect(vis, SIGNAL(clicked(bool)), this,
-		SLOT(VisibilityClicked(bool)));
+	connect(vis, &VisibilityCheckBox::clicked, [this](bool visible) {
+		obs_source_set_enabled(source, visible);
+	});
 }
 
 void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
@@ -58,11 +59,6 @@ void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data)
 				  Q_ARG(QString, QT_UTF8(name)));
 }
 
-void VisibilityItemWidget::VisibilityClicked(bool visible)
-{
-	obs_source_set_enabled(source, visible);
-}
-
 void VisibilityItemWidget::SourceEnabled(bool enabled)
 {
 	if (vis->isChecked() != enabled)

+ 0 - 1
UI/visibility-item-widget.hpp

@@ -29,7 +29,6 @@ private:
 	static void OBSSourceRenamed(void *param, calldata_t *data);
 
 private slots:
-	void VisibilityClicked(bool visible);
 	void SourceEnabled(bool enabled);
 	void SourceRenamed(QString name);
 

+ 4 - 9
UI/volume-control.cpp

@@ -388,8 +388,8 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
 			       "audio_monitoring", OBSMixersOrMonitoringChanged,
 			       this);
 
-	QWidget::connect(slider, SIGNAL(valueChanged(int)), this,
-			 SLOT(SliderChanged(int)));
+	QWidget::connect(slider, &VolumeSlider::valueChanged, this,
+			 &VolControl::SliderChanged);
 	QWidget::connect(mute, &MuteCheckBox::clicked, this,
 			 &VolControl::SetMuted);
 
@@ -1163,11 +1163,6 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
 
 #define CLIP_FLASH_DURATION_MS 1000
 
-void VolumeMeter::ClipEnding()
-{
-	clipping = false;
-}
-
 inline int VolumeMeter::convertToInt(float number)
 {
 	constexpr int min = std::numeric_limits<int>::min();
@@ -1264,7 +1259,7 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
 	} else if (int(magnitude) != 0) {
 		if (!clipping) {
 			QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
-					   SLOT(ClipEnding()));
+					   [&]() { clipping = false; });
 			clipping = true;
 		}
 
@@ -1376,7 +1371,7 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
 	} else {
 		if (!clipping) {
 			QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
-					   SLOT(ClipEnding()));
+					   [&]() { clipping = false; });
 			clipping = true;
 		}
 

+ 0 - 3
UI/volume-control.hpp

@@ -94,9 +94,6 @@ class VolumeMeter : public QWidget {
 
 	friend class VolControl;
 
-private slots:
-	void ClipEnding();
-
 private:
 	obs_volmeter_t *obs_volmeter;
 	static QWeakPointer<VolumeMeterTimer> updateTimer;

+ 8 - 7
UI/window-basic-about.cpp

@@ -61,9 +61,12 @@ OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
 	ui->license->setProperty("themeID", "aboutHLayout");
 	ui->info->setProperty("themeID", "aboutInfo");
 
-	connect(ui->about, SIGNAL(clicked()), this, SLOT(ShowAbout()));
-	connect(ui->authors, SIGNAL(clicked()), this, SLOT(ShowAuthors()));
-	connect(ui->license, SIGNAL(clicked()), this, SLOT(ShowLicense()));
+	connect(ui->about, &ClickableLabel::clicked, this,
+		&OBSAbout::ShowAbout);
+	connect(ui->authors, &ClickableLabel::clicked, this,
+		&OBSAbout::ShowAuthors);
+	connect(ui->license, &ClickableLabel::clicked, this,
+		&OBSAbout::ShowLicense);
 
 	QPointer<OBSAbout> about(this);
 
@@ -74,10 +77,8 @@ OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
 			"application/json");
 		QObject::connect(thread, &RemoteTextThread::Result, main,
 				 &OBSBasic::UpdatePatronJson);
-		QObject::connect(
-			thread,
-			SIGNAL(Result(const QString &, const QString &)), this,
-			SLOT(ShowAbout()));
+		QObject::connect(thread, &RemoteTextThread::Result, this,
+				 &OBSAbout::ShowAbout);
 		main->patronJsonThread.reset(thread);
 		thread->start();
 	} else {

+ 30 - 30
UI/window-basic-auto-config.cpp

@@ -283,38 +283,38 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
 
 	LoadServices(false);
 
-	connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(ServiceChanged()));
-	connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
-		SLOT(ServiceChanged()));
-	connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
-		SLOT(UpdateKeyLink()));
-	connect(ui->customServer, SIGNAL(editingFinished()), this,
-		SLOT(UpdateKeyLink()));
-	connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this,
-		SLOT(ServiceChanged()));
-
-	connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateServerList()));
-
-	connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateKeyLink()));
-	connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateMoreInfoLink()));
-
-	connect(ui->useStreamKeyAdv, &QPushButton::clicked, this,
+	connect(ui->service, &QComboBox::currentIndexChanged, this,
+		&AutoConfigStreamPage::ServiceChanged);
+	connect(ui->customServer, &QLineEdit::textChanged, this,
+		&AutoConfigStreamPage::ServiceChanged);
+	connect(ui->customServer, &QLineEdit::textChanged, this,
+		&AutoConfigStreamPage::UpdateKeyLink);
+	connect(ui->customServer, &QLineEdit::editingFinished, this,
+		&AutoConfigStreamPage::UpdateKeyLink);
+	connect(ui->doBandwidthTest, &QCheckBox::toggled, this,
+		&AutoConfigStreamPage::ServiceChanged);
+
+	connect(ui->service, &QComboBox::currentIndexChanged, this,
+		&AutoConfigStreamPage::UpdateServerList);
+
+	connect(ui->service, &QComboBox::currentIndexChanged, this,
+		&AutoConfigStreamPage::UpdateKeyLink);
+	connect(ui->service, &QComboBox::currentIndexChanged, this,
+		&AutoConfigStreamPage::UpdateMoreInfoLink);
+
+	connect(ui->useStreamKeyAdv, &QPushButton::clicked,
 		[&]() { ui->streamKeyWidget->setVisible(true); });
 
-	connect(ui->key, SIGNAL(textChanged(const QString &)), this,
-		SLOT(UpdateCompleted()));
-	connect(ui->regionUS, SIGNAL(toggled(bool)), this,
-		SLOT(UpdateCompleted()));
-	connect(ui->regionEU, SIGNAL(toggled(bool)), this,
-		SLOT(UpdateCompleted()));
-	connect(ui->regionAsia, SIGNAL(toggled(bool)), this,
-		SLOT(UpdateCompleted()));
-	connect(ui->regionOther, SIGNAL(toggled(bool)), this,
-		SLOT(UpdateCompleted()));
+	connect(ui->key, &QLineEdit::textChanged, this,
+		&AutoConfigStreamPage::UpdateCompleted);
+	connect(ui->regionUS, &QCheckBox::toggled, this,
+		&AutoConfigStreamPage::UpdateCompleted);
+	connect(ui->regionEU, &QCheckBox::toggled, this,
+		&AutoConfigStreamPage::UpdateCompleted);
+	connect(ui->regionAsia, &QCheckBox::toggled, this,
+		&AutoConfigStreamPage::UpdateCompleted);
+	connect(ui->regionOther, &QCheckBox::toggled, this,
+		&AutoConfigStreamPage::UpdateCompleted);
 }
 
 AutoConfigStreamPage::~AutoConfigStreamPage() {}

+ 18 - 45
UI/window-basic-filters.cpp

@@ -89,19 +89,21 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
 	installEventFilter(CreateShortcutFilter());
 
 	connect(ui->asyncFilters->itemDelegate(),
-		SIGNAL(closeEditor(QWidget *)), this,
-		SLOT(AsyncFilterNameEdited(QWidget *)));
+		&QAbstractItemDelegate::closeEditor, [this](QWidget *editor) {
+			FilterNameEdited(editor, ui->asyncFilters);
+		});
 
 	connect(ui->effectFilters->itemDelegate(),
-		SIGNAL(closeEditor(QWidget *)), this,
-		SLOT(EffectFilterNameEdited(QWidget *)));
+		&QAbstractItemDelegate::closeEditor, [this](QWidget *editor) {
+			FilterNameEdited(editor, ui->effectFilters);
+		});
 
 	QPushButton *close = ui->buttonBox->button(QDialogButtonBox::Close);
-	connect(close, SIGNAL(clicked()), this, SLOT(close()));
+	connect(close, &QPushButton::clicked, this, &OBSBasicFilters::close);
 	close->setDefault(true);
 
 	connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults),
-		SIGNAL(clicked()), this, SLOT(ResetFilters()));
+		&QPushButton::clicked, this, &OBSBasicFilters::ResetFilters);
 
 	connect(ui->asyncFilters->model(), &QAbstractItemModel::rowsMoved, this,
 		&OBSBasicFilters::FiltersMoved);
@@ -541,8 +543,8 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
 		QAction *popupItem =
 			new QAction(QT_UTF8(type.name.c_str()), this);
 		popupItem->setData(QT_UTF8(type.type.c_str()));
-		connect(popupItem, SIGNAL(triggered(bool)), this,
-			SLOT(AddFilterFromAction()));
+		connect(popupItem, &QAction::triggered,
+			[this, type]() { AddNewFilter(type.type.c_str()); });
 		popup->addAction(popupItem);
 
 		foundValues = true;
@@ -662,15 +664,6 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 	}
 }
 
-void OBSBasicFilters::AddFilterFromAction()
-{
-	QAction *action = qobject_cast<QAction *>(sender());
-	if (!action)
-		return;
-
-	AddNewFilter(QT_TO_UTF8(action->data().toString()));
-}
-
 void OBSBasicFilters::closeEvent(QCloseEvent *event)
 {
 	QDialog::closeEvent(event);
@@ -931,20 +924,19 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
 		popup.addMenu(addMenu);
 
 	if (item) {
-		const char *dulpicateSlot =
-			async ? SLOT(DuplicateAsyncFilter())
-			      : SLOT(DuplicateEffectFilter());
-
 		popup.addSeparator();
-		popup.addAction(QTStr("Duplicate"), this, dulpicateSlot);
+		popup.addAction(QTStr("Duplicate"), this, [&]() {
+			DuplicateItem(async ? ui->asyncFilters->currentItem()
+					    : ui->effectFilters->currentItem());
+		});
 		popup.addSeparator();
 		popup.addAction(ui->actionRenameFilter);
 		popup.addAction(ui->actionRemoveFilter);
 		popup.addSeparator();
 
 		QAction *copyAction = new QAction(QTStr("Copy"));
-		connect(copyAction, SIGNAL(triggered()), this,
-			SLOT(CopyFilter()));
+		connect(copyAction, &QAction::triggered, this,
+			&OBSBasicFilters::CopyFilter);
 		copyAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_C));
 		ui->effectWidget->addAction(copyAction);
 		ui->asyncWidget->addAction(copyAction);
@@ -953,7 +945,8 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
 
 	QAction *pasteAction = new QAction(QTStr("Paste"));
 	pasteAction->setEnabled(main->copyFilter);
-	connect(pasteAction, SIGNAL(triggered()), this, SLOT(PasteFilter()));
+	connect(pasteAction, &QAction::triggered, this,
+		&OBSBasicFilters::PasteFilter);
 	pasteAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_V));
 	ui->effectWidget->addAction(pasteAction);
 	ui->asyncWidget->addAction(pasteAction);
@@ -1051,16 +1044,6 @@ void OBSBasicFilters::RenameEffectFilter()
 	EditItem(ui->effectFilters->currentItem(), false);
 }
 
-void OBSBasicFilters::DuplicateAsyncFilter()
-{
-	DuplicateItem(ui->asyncFilters->currentItem());
-}
-
-void OBSBasicFilters::DuplicateEffectFilter()
-{
-	DuplicateItem(ui->effectFilters->currentItem());
-}
-
 void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 {
 	QListWidgetItem *listItem = list->currentItem();
@@ -1135,16 +1118,6 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 	editActive = false;
 }
 
-void OBSBasicFilters::AsyncFilterNameEdited(QWidget *editor)
-{
-	FilterNameEdited(editor, ui->asyncFilters);
-}
-
-void OBSBasicFilters::EffectFilterNameEdited(QWidget *editor)
-{
-	FilterNameEdited(editor, ui->effectFilters);
-}
-
 static bool ConfirmReset(QWidget *parent)
 {
 	QMessageBox::StandardButton button;

+ 0 - 7
UI/window-basic-filters.hpp

@@ -87,12 +87,8 @@ private slots:
 	void ReorderFilters();
 	void RenameAsyncFilter();
 	void RenameEffectFilter();
-	void DuplicateAsyncFilter();
-	void DuplicateEffectFilter();
 	void ResetFilters();
 
-	void AddFilterFromAction();
-
 	void on_addAsyncFilter_clicked();
 	void on_removeAsyncFilter_clicked();
 	void on_moveAsyncFilterUp_clicked();
@@ -115,9 +111,6 @@ private slots:
 
 	void on_actionRenameFilter_triggered();
 
-	void AsyncFilterNameEdited(QWidget *editor);
-	void EffectFilterNameEdited(QWidget *editor);
-
 	void CopyFilter();
 	void PasteFilter();
 

+ 16 - 26
UI/window-basic-main-transitions.cpp

@@ -464,14 +464,10 @@ void OBSBasic::on_transitions_currentIndexChanged(int)
 	SetTransition(transition);
 }
 
-void OBSBasic::AddTransition()
+void OBSBasic::AddTransition(const char *id)
 {
-	QAction *action = reinterpret_cast<QAction *>(sender());
-	QString idStr = action->property("id").toString();
-
 	string name;
-	QString placeHolderText =
-		QT_UTF8(obs_source_get_display_name(QT_TO_UTF8(idStr)));
+	QString placeHolderText = QT_UTF8(obs_source_get_display_name(id));
 	QString format = placeHolderText + " (%1)";
 	obs_source_t *source = nullptr;
 	int i = 1;
@@ -490,7 +486,7 @@ void OBSBasic::AddTransition()
 			OBSMessageBox::warning(this,
 					       QTStr("NoNameEntered.Title"),
 					       QTStr("NoNameEntered.Text"));
-			AddTransition();
+			AddTransition(id);
 			return;
 		}
 
@@ -499,12 +495,11 @@ void OBSBasic::AddTransition()
 			OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 					       QTStr("NameExists.Text"));
 
-			AddTransition();
+			AddTransition(id);
 			return;
 		}
 
-		source = obs_source_create_private(QT_TO_UTF8(idStr),
-						   name.c_str(), NULL);
+		source = obs_source_create_private(id, name.c_str(), NULL);
 		InitTransition(source);
 		ui->transitions->addItem(
 			QT_UTF8(name.c_str()),
@@ -533,10 +528,9 @@ void OBSBasic::on_transitionAdd_clicked()
 		if (obs_is_source_configurable(id)) {
 			const char *name = obs_source_get_display_name(id);
 			QAction *action = new QAction(name, this);
-			action->setProperty("id", id);
 
-			connect(action, SIGNAL(triggered()), this,
-				SLOT(AddTransition()));
+			connect(action, &QAction::triggered,
+				[this, id]() { AddTransition(id); });
 
 			menu.addAction(action);
 			foundConfigurableTransitions = true;
@@ -578,12 +572,8 @@ void OBSBasic::on_transitionRemove_clicked()
 	RefreshQuickTransitions();
 }
 
-void OBSBasic::RenameTransition()
+void OBSBasic::RenameTransition(OBSSource transition)
 {
-	QAction *action = reinterpret_cast<QAction *>(sender());
-	QVariant variant = action->property("transition");
-	OBSSource transition = variant.value<OBSSource>();
-
 	string name;
 	QString placeHolderText = QT_UTF8(obs_source_get_name(transition));
 	obs_source_t *source = nullptr;
@@ -598,7 +588,7 @@ void OBSBasic::RenameTransition()
 	if (name.empty()) {
 		OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"),
 				       QTStr("NoNameEntered.Text"));
-		RenameTransition();
+		RenameTransition(transition);
 		return;
 	}
 
@@ -607,12 +597,12 @@ void OBSBasic::RenameTransition()
 		OBSMessageBox::warning(this, QTStr("NameExists.Title"),
 				       QTStr("NameExists.Text"));
 
-		RenameTransition();
+		RenameTransition(transition);
 		return;
 	}
 
 	obs_source_set_name(transition, name.c_str());
-	int idx = ui->transitions->findData(variant);
+	int idx = ui->transitions->findData(QVariant::fromValue(transition));
 	if (idx != -1) {
 		ui->transitions->setItemText(idx, QT_UTF8(name.c_str()));
 
@@ -639,8 +629,8 @@ void OBSBasic::on_transitionProps_clicked()
 	QMenu menu(this);
 
 	QAction *action = new QAction(QTStr("Rename"), &menu);
-	connect(action, SIGNAL(triggered()), this, SLOT(RenameTransition()));
-	action->setProperty("transition", QVariant::fromValue(source));
+	connect(action, &QAction::triggered,
+		[this, source]() { RenameTransition(source); });
 	menu.addAction(action);
 
 	action = new QAction(QTStr("Properties"), &menu);
@@ -822,7 +812,7 @@ void OBSBasic::CreateProgramOptions()
 	tBar->setProperty("themeID", "tBarSlider");
 
 	connect(tBar, &QSlider::valueChanged, this, &OBSBasic::TBarChanged);
-	connect(tBar, SIGNAL(sliderReleased()), this, SLOT(TBarReleased()));
+	connect(tBar, &QSlider::sliderReleased, this, &OBSBasic::TBarReleased);
 
 	layout->addStretch(0);
 	layout->addLayout(mainButtonLayout);
@@ -1274,8 +1264,8 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
 	if (curId && obs_is_source_configurable(curId)) {
 		menu->addSeparator();
 		menu->addAction(QTStr("Properties"), this,
-				visible ? SLOT(ShowTransitionProperties())
-					: SLOT(HideTransitionProperties()));
+				visible ? &OBSBasic::ShowTransitionProperties
+					: &OBSBasic::HideTransitionProperties);
 	}
 
 	auto copyTransition = [this](QAction *, bool visible) {

+ 110 - 126
UI/window-basic-main.cpp

@@ -291,7 +291,7 @@ void setupDockAction(QDockWidget *dock)
 	};
 
 	// Replace the slot connected by default
-	action->disconnect(SIGNAL(triggered(bool)));
+	QObject::disconnect(action, &QAction::triggered, nullptr, 0);
 	dock->connect(action, &QAction::triggered, newToggleView);
 
 	// Make the action unable to be disabled
@@ -396,28 +396,29 @@ OBSBasic::OBSBasic(QWidget *parent)
 
 	UpdateTitleBar();
 
-	connect(ui->scenes->itemDelegate(), SIGNAL(closeEditor(QWidget *)),
-		this, SLOT(SceneNameEdited(QWidget *)));
+	connect(ui->scenes->itemDelegate(), &QAbstractItemDelegate::closeEditor,
+		this, &OBSBasic::SceneNameEdited);
 
 	cpuUsageInfo = os_cpu_usage_info_start();
 	cpuUsageTimer = new QTimer(this);
-	connect(cpuUsageTimer.data(), SIGNAL(timeout()), ui->statusbar,
-		SLOT(UpdateCPUUsage()));
+	connect(cpuUsageTimer.data(), &QTimer::timeout, ui->statusbar,
+		&OBSBasicStatusBar::UpdateCPUUsage);
 	cpuUsageTimer->start(3000);
 
 	diskFullTimer = new QTimer(this);
-	connect(diskFullTimer, SIGNAL(timeout()), this,
-		SLOT(CheckDiskSpaceRemaining()));
+	connect(diskFullTimer, &QTimer::timeout, this,
+		&OBSBasic::CheckDiskSpaceRemaining);
 
 	renameScene = new QAction(QTStr("Rename"), ui->scenesDock);
 	renameScene->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-	connect(renameScene, SIGNAL(triggered()), this, SLOT(EditSceneName()));
+	connect(renameScene, &QAction::triggered, this,
+		&OBSBasic::EditSceneName);
 	ui->scenesDock->addAction(renameScene);
 
 	renameSource = new QAction(QTStr("Rename"), ui->sourcesDock);
 	renameSource->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-	connect(renameSource, SIGNAL(triggered()), this,
-		SLOT(EditSceneItemName()));
+	connect(renameSource, &QAction::triggered, this,
+		&OBSBasic::EditSceneItemName);
 	ui->sourcesDock->addAction(renameSource);
 
 #ifdef __APPLE__
@@ -522,11 +523,11 @@ OBSBasic::OBSBasic(QWidget *parent)
 	statsDock->move(newPos);
 
 	ui->previewDisabledWidget->setContextMenuPolicy(Qt::CustomContextMenu);
-	connect(ui->enablePreviewButton, SIGNAL(clicked()), this,
-		SLOT(TogglePreview()));
+	connect(ui->enablePreviewButton, &QPushButton::clicked, this,
+		&OBSBasic::TogglePreview);
 
-	connect(ui->scenes, SIGNAL(scenesReordered()), this,
-		SLOT(ScenesReordered()));
+	connect(ui->scenes, &SceneTree::scenesReordered,
+		[]() { OBSProjector::UpdateMultiviewProjectors(); });
 
 	connect(ui->broadcastButton, &QPushButton::clicked, this,
 		&OBSBasic::BroadcastButtonClicked);
@@ -2277,7 +2278,7 @@ void OBSBasic::OBSInit()
 	ui->viewMenu->addSeparator();
 
 	AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this,
-				 SLOT(OpenMultiviewProjector()));
+				 &OBSBasic::OpenMultiviewProjector);
 	connect(ui->viewMenu->menuAction(), &QAction::hovered, this,
 		&OBSBasic::UpdateMultiviewProjectorMenu);
 
@@ -2540,7 +2541,7 @@ void OBSBasic::UpdateMultiviewProjectorMenu()
 {
 	ui->multiviewProjectorMenu->clear();
 	AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this,
-				 SLOT(OpenMultiviewProjector()));
+				 &OBSBasic::OpenMultiviewProjector);
 }
 
 void OBSBasic::InitHotkeys()
@@ -5040,7 +5041,7 @@ void OBSBasic::closeEvent(QCloseEvent *event)
 	 * could be inside of an Auth::LoadUI call.  Keep trying once per
 	 * second until we've exit any known sub-loops. */
 	if (os_atomic_load_long(&insideEventLoop) != 0) {
-		QTimer::singleShot(1000, this, SLOT(close()));
+		QTimer::singleShot(1000, this, &OBSBasic::close);
 		event->ignore();
 		return;
 	}
@@ -5048,7 +5049,7 @@ void OBSBasic::closeEvent(QCloseEvent *event)
 #ifdef YOUTUBE_ENABLED
 	/* Also don't close the window if the youtube stream check is active */
 	if (youtubeStreamCheckThread) {
-		QTimer::singleShot(1000, this, SLOT(close()));
+		QTimer::singleShot(1000, this, &OBSBasic::close);
 		event->ignore();
 		return;
 	}
@@ -5245,7 +5246,7 @@ void OBSBasic::on_action_Settings_triggered()
 	 * once per second until we've exit any known sub-loops. */
 	if (os_atomic_load_long(&insideEventLoop) != 0) {
 		QTimer::singleShot(1000, this,
-				   SLOT(on_action_Settings_triggered()));
+				   &OBSBasic::on_action_Settings_triggered);
 		return;
 	}
 
@@ -5398,10 +5399,9 @@ void OBSBasic::EditSceneName()
 	item->setFlags(flags);
 }
 
-void OBSBasic::AddProjectorMenuMonitors(QMenu *parent, QObject *target,
-					const char *slot)
+QList<QString> OBSBasic::GetProjectorMenuMonitorsFormatted()
 {
-	QAction *action;
+	QList<QString> projectorsFormatted;
 	QList<QScreen *> screens = QGuiApplication::screens();
 	for (int i = 0; i < screens.size(); i++) {
 		QScreen *screen = screens[i];
@@ -5438,10 +5438,9 @@ void OBSBasic::AddProjectorMenuMonitors(QMenu *parent, QObject *target,
 						     ratio),
 				     QString::number(screenGeometry.x()),
 				     QString::number(screenGeometry.y()));
-
-		action = parent->addAction(str, target, slot);
-		action->setProperty("monitor", i);
+		projectorsFormatted.push_back(str);
 	}
+	return projectorsFormatted;
 }
 
 void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
@@ -5452,23 +5451,23 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 	QMenu order(QTStr("Basic.MainMenu.Edit.Order"), this);
 
 	popup.addAction(QTStr("Add"), this,
-			SLOT(on_actionAddScene_triggered()));
+			&OBSBasic::on_actionAddScene_triggered);
 
 	if (item) {
 		QAction *copyFilters = new QAction(QTStr("Copy.Filters"), this);
 		copyFilters->setEnabled(false);
-		connect(copyFilters, SIGNAL(triggered()), this,
-			SLOT(SceneCopyFilters()));
+		connect(copyFilters, &QAction::triggered, this,
+			&OBSBasic::SceneCopyFilters);
 		QAction *pasteFilters =
 			new QAction(QTStr("Paste.Filters"), this);
 		pasteFilters->setEnabled(
 			!obs_weak_source_expired(copyFiltersSource));
-		connect(pasteFilters, SIGNAL(triggered()), this,
-			SLOT(ScenePasteFilters()));
+		connect(pasteFilters, &QAction::triggered, this,
+			&OBSBasic::ScenePasteFilters);
 
 		popup.addSeparator();
 		popup.addAction(QTStr("Duplicate"), this,
-				SLOT(DuplicateSelectedScene()));
+				&OBSBasic::DuplicateSelectedScene);
 		popup.addAction(copyFilters);
 		popup.addAction(pasteFilters);
 		popup.addSeparator();
@@ -5477,14 +5476,14 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 		popup.addSeparator();
 
 		order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveUp"), this,
-				SLOT(on_actionSceneUp_triggered()));
+				&OBSBasic::on_actionSceneUp_triggered);
 		order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveDown"),
-				this, SLOT(on_actionSceneDown_triggered()));
+				this, &OBSBasic::on_actionSceneDown_triggered);
 		order.addSeparator();
 		order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveToTop"),
-				this, SLOT(MoveSceneToTop()));
+				this, &OBSBasic::MoveSceneToTop);
 		order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveToBottom"),
-				this, SLOT(MoveSceneToBottom()));
+				this, &OBSBasic::MoveSceneToBottom);
 		popup.addMenu(&order);
 
 		popup.addSeparator();
@@ -5492,18 +5491,18 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 		delete sceneProjectorMenu;
 		sceneProjectorMenu = new QMenu(QTStr("SceneProjector"));
 		AddProjectorMenuMonitors(sceneProjectorMenu, this,
-					 SLOT(OpenSceneProjector()));
+					 &OBSBasic::OpenSceneProjector);
 		popup.addMenu(sceneProjectorMenu);
 
 		QAction *sceneWindow = popup.addAction(
-			QTStr("SceneWindow"), this, SLOT(OpenSceneWindow()));
+			QTStr("SceneWindow"), this, &OBSBasic::OpenSceneWindow);
 
 		popup.addAction(sceneWindow);
 		popup.addAction(QTStr("Screenshot.Scene"), this,
-				SLOT(ScreenshotScene()));
+				&OBSBasic::ScreenshotScene);
 		popup.addSeparator();
 		popup.addAction(QTStr("Filters"), this,
-				SLOT(OpenSceneFilters()));
+				&OBSBasic::OpenSceneFilters);
 
 		popup.addSeparator();
 
@@ -5546,8 +5545,8 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 	QAction *gridAction = new QAction(grid ? QTStr("Basic.Main.ListMode")
 					       : QTStr("Basic.Main.GridMode"),
 					  this);
-	connect(gridAction, SIGNAL(triggered()), this,
-		SLOT(GridActionClicked()));
+	connect(gridAction, &QAction::triggered, this,
+		&OBSBasic::GridActionClicked);
 	popup.addAction(gridAction);
 
 	popup.exec(QCursor::pos());
@@ -5718,11 +5717,11 @@ QMenu *OBSBasic::AddDeinterlacingMenu(QMenu *menu, obs_source_t *source)
 		obs_source_get_deinterlace_field_order(source);
 	QAction *action;
 
-#define ADD_MODE(name, mode)                                    \
-	action = menu->addAction(QTStr("" name), this,          \
-				 SLOT(SetDeinterlacingMode())); \
-	action->setProperty("mode", (int)mode);                 \
-	action->setCheckable(true);                             \
+#define ADD_MODE(name, mode)                                       \
+	action = menu->addAction(QTStr("" name), this,             \
+				 &OBSBasic::SetDeinterlacingMode); \
+	action->setProperty("mode", (int)mode);                    \
+	action->setCheckable(true);                                \
 	action->setChecked(deinterlaceMode == mode);
 
 	ADD_MODE("Disable", OBS_DEINTERLACE_MODE_DISABLE);
@@ -5740,7 +5739,7 @@ QMenu *OBSBasic::AddDeinterlacingMenu(QMenu *menu, obs_source_t *source)
 
 #define ADD_ORDER(name, order)                                       \
 	action = menu->addAction(QTStr("Deinterlacing." name), this, \
-				 SLOT(SetDeinterlacingOrder()));     \
+				 &OBSBasic::SetDeinterlacingOrder);  \
 	action->setProperty("order", (int)order);                    \
 	action->setCheckable(true);                                  \
 	action->setChecked(deinterlaceOrder == order);
@@ -5766,11 +5765,11 @@ QMenu *OBSBasic::AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item)
 	obs_scale_type scaleFilter = obs_sceneitem_get_scale_filter(item);
 	QAction *action;
 
-#define ADD_MODE(name, mode)                                                   \
-	action =                                                               \
-		menu->addAction(QTStr("" name), this, SLOT(SetScaleFilter())); \
-	action->setProperty("mode", (int)mode);                                \
-	action->setCheckable(true);                                            \
+#define ADD_MODE(name, mode)                                 \
+	action = menu->addAction(QTStr("" name), this,       \
+				 &OBSBasic::SetScaleFilter); \
+	action->setProperty("mode", (int)mode);              \
+	action->setCheckable(true);                          \
 	action->setChecked(scaleFilter == mode);
 
 	ADD_MODE("Disable", OBS_SCALE_DISABLE);
@@ -5800,11 +5799,11 @@ QMenu *OBSBasic::AddBlendingMethodMenu(QMenu *menu, obs_sceneitem_t *item)
 		obs_sceneitem_get_blending_method(item);
 	QAction *action;
 
-#define ADD_MODE(name, method)                               \
-	action = menu->addAction(QTStr("" name), this,       \
-				 SLOT(SetBlendingMethod())); \
-	action->setProperty("method", (int)method);          \
-	action->setCheckable(true);                          \
+#define ADD_MODE(name, method)                                  \
+	action = menu->addAction(QTStr("" name), this,          \
+				 &OBSBasic::SetBlendingMethod); \
+	action->setProperty("method", (int)method);             \
+	action->setCheckable(true);                             \
 	action->setChecked(blendingMethod == method);
 
 	ADD_MODE("BlendingMethod.Default", OBS_BLEND_METHOD_DEFAULT);
@@ -5829,11 +5828,11 @@ QMenu *OBSBasic::AddBlendingModeMenu(QMenu *menu, obs_sceneitem_t *item)
 	obs_blending_type blendingMode = obs_sceneitem_get_blending_mode(item);
 	QAction *action;
 
-#define ADD_MODE(name, mode)                               \
-	action = menu->addAction(QTStr("" name), this,     \
-				 SLOT(SetBlendingMode())); \
-	action->setProperty("mode", (int)mode);            \
-	action->setCheckable(true);                        \
+#define ADD_MODE(name, mode)                                  \
+	action = menu->addAction(QTStr("" name), this,        \
+				 &OBSBasic::SetBlendingMode); \
+	action->setProperty("mode", (int)mode);               \
+	action->setCheckable(true);                           \
 	action->setChecked(blendingMode == mode);
 
 	ADD_MODE("BlendingMode.Normal", OBS_BLEND_NORMAL);
@@ -5871,13 +5870,13 @@ QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu,
 	obs_data_set_default_int(privData, "color-preset", 0);
 	int preset = obs_data_get_int(privData, "color-preset");
 
-	action = menu->addAction(QTStr("Clear"), this, +SLOT(ColorChange()));
+	action = menu->addAction(QTStr("Clear"), this, &OBSBasic::ColorChange);
 	action->setCheckable(true);
 	action->setProperty("bgColor", 0);
 	action->setChecked(preset == 0);
 
 	action = menu->addAction(QTStr("CustomColor"), this,
-				 +SLOT(ColorChange()));
+				 &OBSBasic::ColorChange);
 	action->setCheckable(true);
 	action->setProperty("bgColor", 1);
 	action->setChecked(preset == 1);
@@ -5895,8 +5894,8 @@ QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu,
 			colorButton->setStyleSheet("border: 2px solid black");
 
 		colorButton->setProperty("bgColor", i);
-		select->connect(colorButton, SIGNAL(released()), this,
-				SLOT(ColorChange()));
+		select->connect(colorButton, &QPushButton::released, this,
+				&OBSBasic::ColorChange);
 	}
 
 	menu->addAction(widgetAction);
@@ -5927,7 +5926,7 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 	if (preview) {
 		QAction *action = popup.addAction(
 			QTStr("Basic.Main.PreviewConextMenu.Enable"), this,
-			SLOT(TogglePreview()));
+			&OBSBasic::TogglePreview);
 		action->setCheckable(true);
 		action->setChecked(
 			obs_display_enabled(ui->preview->GetDisplay()));
@@ -5939,18 +5938,18 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 
 		previewProjectorSource = new QMenu(QTStr("PreviewProjector"));
 		AddProjectorMenuMonitors(previewProjectorSource, this,
-					 SLOT(OpenPreviewProjector()));
+					 &OBSBasic::OpenPreviewProjector);
 
 		popup.addMenu(previewProjectorSource);
 
 		QAction *previewWindow =
 			popup.addAction(QTStr("PreviewWindow"), this,
-					SLOT(OpenPreviewWindow()));
+					&OBSBasic::OpenPreviewWindow);
 
 		popup.addAction(previewWindow);
 
 		popup.addAction(QTStr("Screenshot.Preview"), this,
-				SLOT(ScreenshotScene()));
+				&OBSBasic::ScreenshotScene);
 
 		popup.addSeparator();
 	}
@@ -5962,12 +5961,12 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 	if (ui->sources->MultipleBaseSelected()) {
 		popup.addSeparator();
 		popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources,
-				SLOT(GroupSelectedItems()));
+				&SourceTree::GroupSelectedItems);
 
 	} else if (ui->sources->GroupsSelected()) {
 		popup.addSeparator();
 		popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources,
-				SLOT(UngroupSelectedGroups()));
+				&SourceTree::UngroupSelectedGroups);
 	}
 
 	popup.addSeparator();
@@ -6012,7 +6011,7 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 		if (hasAudio) {
 			QAction *actionHideMixer =
 				popup.addAction(QTStr("HideMixer"), this,
-						SLOT(ToggleHideMixer()));
+						&OBSBasic::ToggleHideMixer);
 			actionHideMixer->setCheckable(true);
 			actionHideMixer->setChecked(SourceMixerHidden(source));
 			popup.addSeparator();
@@ -6021,7 +6020,7 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 		if (hasVideo) {
 			QAction *resizeOutput = popup.addAction(
 				QTStr("ResizeOutputSizeOfSource"), this,
-				SLOT(ResizeOutputSizeOfSource()));
+				&OBSBasic::ResizeOutputSizeOfSource);
 
 			int width = obs_source_get_width(source);
 			int height = obs_source_get_height(source);
@@ -6054,26 +6053,28 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 			popup.addSeparator();
 
 			sourceProjector = new QMenu(QTStr("SourceProjector"));
-			AddProjectorMenuMonitors(sourceProjector, this,
-						 SLOT(OpenSourceProjector()));
+			AddProjectorMenuMonitors(
+				sourceProjector, this,
+				&OBSBasic::OpenSourceProjector);
 			popup.addMenu(sourceProjector);
 			popup.addAction(QTStr("SourceWindow"), this,
-					SLOT(OpenSourceWindow()));
+					&OBSBasic::OpenSourceWindow);
 
 			popup.addAction(QTStr("Screenshot.Source"), this,
-					SLOT(ScreenshotSelectedSource()));
+					&OBSBasic::ScreenshotSelectedSource);
 		}
 
 		popup.addSeparator();
 
 		if (flags & OBS_SOURCE_INTERACTION)
 			popup.addAction(QTStr("Interact"), this,
-					SLOT(on_actionInteract_triggered()));
+					&OBSBasic::on_actionInteract_triggered);
 
-		popup.addAction(QTStr("Filters"), this, SLOT(OpenFilters()));
+		popup.addAction(QTStr("Filters"), this,
+				[&]() { OpenFilters(); });
 		QAction *action = popup.addAction(
 			QTStr("Properties"), this,
-			SLOT(on_actionSourceProperties_triggered()));
+			&OBSBasic::on_actionSourceProperties_triggered);
 		action->setEnabled(obs_source_configurable(source));
 	}
 
@@ -6157,9 +6158,8 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu()
 						const char *name) {
 		QString qname = QT_UTF8(name);
 		QAction *popupItem = new QAction(qname, this);
-		popupItem->setData(QT_UTF8(type));
-		connect(popupItem, SIGNAL(triggered(bool)), this,
-			SLOT(AddSourceFromAction()));
+		connect(popupItem, &QAction::triggered,
+			[this, type]() { AddSource(type); });
 
 		QIcon icon;
 
@@ -6194,10 +6194,9 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu()
 
 	popup->addSeparator();
 	QAction *addGroup = new QAction(QTStr("Group"), this);
-	addGroup->setData(QT_UTF8("group"));
 	addGroup->setIcon(GetGroupIcon());
-	connect(addGroup, SIGNAL(triggered(bool)), this,
-		SLOT(AddSourceFromAction()));
+	connect(addGroup, &QAction::triggered,
+		[this]() { AddSource("group"); });
 	popup->addAction(addGroup);
 
 	if (!foundDeprecated) {
@@ -6217,15 +6216,6 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu()
 	return popup;
 }
 
-void OBSBasic::AddSourceFromAction()
-{
-	QAction *action = qobject_cast<QAction *>(sender());
-	if (!action)
-		return;
-
-	AddSource(QT_TO_UTF8(action->data().toString()));
-}
-
 void OBSBasic::AddSourcePopupMenu(const QPoint &pos)
 {
 	if (!GetCurrentScene()) {
@@ -7341,9 +7331,9 @@ void OBSBasic::StreamDelayStarting(int sec)
 
 	startStreamMenu = new QMenu();
 	startStreamMenu->addAction(QTStr("Basic.Main.StopStreaming"), this,
-				   SLOT(StopStreaming()));
+				   &OBSBasic::StopStreaming);
 	startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this,
-				   SLOT(ForceStopStreaming()));
+				   &OBSBasic::ForceStopStreaming);
 	ui->streamButton->setMenu(startStreamMenu);
 
 	ui->statusbar->StreamDelayStarting(sec);
@@ -7367,9 +7357,9 @@ void OBSBasic::StreamDelayStopping(int sec)
 
 	startStreamMenu = new QMenu();
 	startStreamMenu->addAction(QTStr("Basic.Main.StartStreaming"), this,
-				   SLOT(StartStreaming()));
+				   &OBSBasic::StartStreaming);
 	startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this,
-				   SLOT(ForceStopStreaming()));
+				   &OBSBasic::ForceStopStreaming);
 	ui->streamButton->setMenu(startStreamMenu);
 
 	ui->statusbar->StreamDelayStopping(sec);
@@ -8311,18 +8301,18 @@ void OBSBasic::ProgramViewContextMenuRequested()
 
 	studioProgramProjector = new QMenu(QTStr("StudioProgramProjector"));
 	AddProjectorMenuMonitors(studioProgramProjector, this,
-				 SLOT(OpenStudioProgramProjector()));
+				 &OBSBasic::OpenStudioProgramProjector);
 
 	popup.addMenu(studioProgramProjector);
 
 	QAction *studioProgramWindow =
 		popup.addAction(QTStr("StudioProgramWindow"), this,
-				SLOT(OpenStudioProgramWindow()));
+				&OBSBasic::OpenStudioProgramWindow);
 
 	popup.addAction(studioProgramWindow);
 
 	popup.addAction(QTStr("Screenshot.StudioProgram"), this,
-			SLOT(ScreenshotProgram()));
+			&OBSBasic::ScreenshotProgram);
 
 	popup.exec(QCursor::pos());
 }
@@ -8334,16 +8324,16 @@ void OBSBasic::on_previewDisabledWidget_customContextMenuRequested()
 
 	QAction *action =
 		popup.addAction(QTStr("Basic.Main.PreviewConextMenu.Enable"),
-				this, SLOT(TogglePreview()));
+				this, &OBSBasic::TogglePreview);
 	action->setCheckable(true);
 	action->setChecked(obs_display_enabled(ui->preview->GetDisplay()));
 
 	previewProjectorMain = new QMenu(QTStr("PreviewProjector"));
 	AddProjectorMenuMonitors(previewProjectorMain, this,
-				 SLOT(OpenPreviewProjector()));
+				 &OBSBasic::OpenPreviewProjector);
 
 	QAction *previewWindow = popup.addAction(QTStr("PreviewWindow"), this,
-						 SLOT(OpenPreviewWindow()));
+						 &OBSBasic::OpenPreviewWindow);
 
 	popup.addMenu(previewProjectorMain);
 	popup.addAction(previewWindow);
@@ -9654,7 +9644,7 @@ void OBSBasic::SetShowing(bool showing)
 
 		if (showHide)
 			showHide->setText(QTStr("Basic.SystemTray.Show"));
-		QTimer::singleShot(0, this, SLOT(hide()));
+		QTimer::singleShot(0, this, &OBSBasic::hide);
 
 		if (previewEnabled)
 			EnablePreviewDisplay(false);
@@ -9666,7 +9656,7 @@ void OBSBasic::SetShowing(bool showing)
 	} else if (showing && !isVisible()) {
 		if (showHide)
 			showHide->setText(QTStr("Basic.SystemTray.Hide"));
-		QTimer::singleShot(0, this, SLOT(show()));
+		QTimer::singleShot(0, this, &OBSBasic::show);
 
 		if (previewEnabled)
 			EnablePreviewDisplay(true);
@@ -9746,9 +9736,9 @@ void OBSBasic::SystemTrayInit()
 	previewProjector = new QMenu(QTStr("PreviewProjector"));
 	studioProgramProjector = new QMenu(QTStr("StudioProgramProjector"));
 	AddProjectorMenuMonitors(previewProjector, this,
-				 SLOT(OpenPreviewProjector()));
+				 &OBSBasic::OpenPreviewProjector);
 	AddProjectorMenuMonitors(studioProgramProjector, this,
-				 SLOT(OpenStudioProgramProjector()));
+				 &OBSBasic::OpenStudioProgramProjector);
 	trayMenu->addAction(showHide);
 	trayMenu->addSeparator();
 	trayMenu->addMenu(previewProjector);
@@ -9771,19 +9761,18 @@ void OBSBasic::SystemTrayInit()
 	if (Active())
 		OnActivate(true);
 
-	connect(trayIcon.data(),
-		SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this,
-		SLOT(IconActivated(QSystemTrayIcon::ActivationReason)));
-	connect(showHide, SIGNAL(triggered()), this, SLOT(ToggleShowHide()));
-	connect(sysTrayStream, SIGNAL(triggered()), this,
-		SLOT(on_streamButton_clicked()));
-	connect(sysTrayRecord, SIGNAL(triggered()), this,
-		SLOT(on_recordButton_clicked()));
+	connect(trayIcon.data(), &QSystemTrayIcon::activated, this,
+		&OBSBasic::IconActivated);
+	connect(showHide, &QAction::triggered, this, &OBSBasic::ToggleShowHide);
+	connect(sysTrayStream, &QAction::triggered, this,
+		&OBSBasic::on_streamButton_clicked);
+	connect(sysTrayRecord, &QAction::triggered, this,
+		&OBSBasic::on_recordButton_clicked);
 	connect(sysTrayReplayBuffer.data(), &QAction::triggered, this,
 		&OBSBasic::ReplayBufferClicked);
 	connect(sysTrayVirtualCam.data(), &QAction::triggered, this,
 		&OBSBasic::VCamButtonClicked);
-	connect(exit, SIGNAL(triggered()), this, SLOT(close()));
+	connect(exit, &QAction::triggered, this, &OBSBasic::close);
 }
 
 void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason)
@@ -9792,9 +9781,9 @@ void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason)
 	previewProjector->clear();
 	studioProgramProjector->clear();
 	AddProjectorMenuMonitors(previewProjector, this,
-				 SLOT(OpenPreviewProjector()));
+				 &OBSBasic::OpenPreviewProjector);
 	AddProjectorMenuMonitors(studioProgramProjector, this,
-				 SLOT(OpenStudioProgramProjector()));
+				 &OBSBasic::OpenStudioProgramProjector);
 
 #ifdef __APPLE__
 	UNUSED_PARAMETER(reason);
@@ -10789,11 +10778,6 @@ void OBSBasic::CheckDiskSpaceRemaining()
 	}
 }
 
-void OBSBasic::ScenesReordered()
-{
-	OBSProjector::UpdateMultiviewProjectors();
-}
-
 void OBSBasic::ResetStatsHotkey()
 {
 	QList<OBSBasicStats *> list = findChildren<OBSBasicStats *>();

+ 15 - 8
UI/window-basic-main.hpp

@@ -758,8 +758,8 @@ private slots:
 
 	void ProcessHotkey(obs_hotkey_id id, bool pressed);
 
-	void AddTransition();
-	void RenameTransition();
+	void AddTransition(const char *id);
+	void RenameTransition(OBSSource transition);
 	void TransitionClicked();
 	void TransitionStopped();
 	void TransitionFullyStopped();
@@ -812,8 +812,6 @@ private slots:
 	void CheckDiskSpaceRemaining();
 	void OpenSavedProjector(SavedProjectorInfo *info);
 
-	void ScenesReordered();
-
 	void ResetStatsHotkey();
 
 	void SetImageIcon(const QIcon &icon);
@@ -986,8 +984,19 @@ public:
 	const char *GetCurrentOutputPath();
 
 	void DeleteProjector(OBSProjector *projector);
-	void AddProjectorMenuMonitors(QMenu *parent, QObject *target,
-				      const char *slot);
+
+	static QList<QString> GetProjectorMenuMonitorsFormatted();
+	template<typename Receiver, typename... Args>
+	static void AddProjectorMenuMonitors(QMenu *parent, Receiver *target,
+					     void (Receiver::*slot)(Args...))
+	{
+		auto projectors = GetProjectorMenuMonitorsFormatted();
+		for (int i = 0; i < projectors.size(); i++) {
+			QString str = projectors[i];
+			QAction *action = parent->addAction(str, target, slot);
+			action->setProperty("monitor", i);
+		}
+	}
 
 	QIcon GetSourceIcon(const char *id) const;
 	QIcon GetGroupIcon() const;
@@ -1174,8 +1183,6 @@ private slots:
 
 	void updateCheckFinished();
 
-	void AddSourceFromAction();
-
 	void MoveSceneToTop();
 	void MoveSceneToBottom();
 

+ 2 - 2
UI/window-basic-properties.cpp

@@ -84,8 +84,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_)
 	ui->propertiesLayout->addWidget(view);
 
 	if (type == OBS_SOURCE_TYPE_TRANSITION) {
-		connect(view, SIGNAL(PropertiesRefreshed()), this,
-			SLOT(AddPreviewButton()));
+		connect(view, &OBSPropertiesView::PropertiesRefreshed, this,
+			&OBSBasicProperties::AddPreviewButton);
 	}
 
 	view->show();

+ 16 - 16
UI/window-basic-settings-stream.cpp

@@ -84,10 +84,10 @@ void OBSBasicSettings::InitStreamPage()
 	ui->twitchAddonDropdown->addItem(
 		QTStr("Basic.Settings.Stream.TTVAddon.Both"));
 
-	connect(ui->ignoreRecommended, SIGNAL(clicked(bool)), this,
-		SLOT(DisplayEnforceWarning(bool)));
-	connect(ui->ignoreRecommended, SIGNAL(toggled(bool)), this,
-		SLOT(UpdateResFPSLimits()));
+	connect(ui->ignoreRecommended, &QCheckBox::clicked, this,
+		&OBSBasicSettings::DisplayEnforceWarning);
+	connect(ui->ignoreRecommended, &QCheckBox::toggled, this,
+		&OBSBasicSettings::UpdateResFPSLimits);
 }
 
 void OBSBasicSettings::LoadStream1Settings()
@@ -870,10 +870,10 @@ void OBSBasicSettings::UpdateVodTrackSetting()
 						     &pos, nullptr);
 	ui->simpleStreamingLayout->insertRow(pos + 1, nullptr, simpleVodTrack);
 
-	HookWidget(simpleVodTrack, SIGNAL(clicked(bool)),
-		   SLOT(OutputsChanged()));
-	connect(ui->simpleOutAdvanced, SIGNAL(toggled(bool)),
-		simpleVodTrack.data(), SLOT(setVisible(bool)));
+	HookWidget(simpleVodTrack.data(), &QCheckBox::clicked,
+		   &OBSBasicSettings::OutputsChanged);
+	connect(ui->simpleOutAdvanced, &QCheckBox::toggled,
+		simpleVodTrack.data(), &QCheckBox::setVisible);
 
 	/* -------------------------------------- */
 	/* advanced output mode vod track widgets */
@@ -889,12 +889,12 @@ void OBSBasicSettings::UpdateVodTrackSetting()
 		vodTrack[i] = new QRadioButton(QString::number(i + 1));
 		vodTrackLayout->addWidget(vodTrack[i]);
 
-		HookWidget(vodTrack[i], SIGNAL(clicked(bool)),
-			   SLOT(OutputsChanged()));
+		HookWidget(vodTrack[i].data(), &QRadioButton::clicked,
+			   &OBSBasicSettings::OutputsChanged);
 	}
 
-	HookWidget(vodTrackCheckbox, SIGNAL(clicked(bool)),
-		   SLOT(OutputsChanged()));
+	HookWidget(vodTrackCheckbox.data(), &QCheckBox::clicked,
+		   &OBSBasicSettings::OutputsChanged);
 
 	vodTrackLayout->addStretch();
 	vodTrackLayout->setContentsMargins(0, 0, 0, 0);
@@ -908,8 +908,8 @@ void OBSBasicSettings::UpdateVodTrackSetting()
 	vodTrackCheckbox->setChecked(vodTrackEnabled);
 	vodTrackContainer->setEnabled(vodTrackEnabled);
 
-	connect(vodTrackCheckbox, SIGNAL(clicked(bool)), vodTrackContainer,
-		SLOT(setEnabled(bool)));
+	connect(vodTrackCheckbox, &QCheckBox::clicked, vodTrackContainer,
+		&QWidget::setEnabled);
 
 	int trackIndex =
 		config_get_int(main->Config(), "AdvOut", "VodTrackIndex");
@@ -1218,8 +1218,8 @@ bool OBSBasicSettings::UpdateResFPSLimits()
 		ui->outputResolution->clear();
 		ui->outputResolution->setEditable(false);
 		HookWidget(ui->outputResolution,
-			   SIGNAL(currentIndexChanged(int)),
-			   SLOT(VideoChangedResolution()));
+			   &QComboBox::currentIndexChanged,
+			   &OBSBasicSettings::VideoChangedResolution);
 
 		int new_res_index = -1;
 

+ 149 - 154
UI/window-basic-settings.cpp

@@ -389,31 +389,25 @@ static inline void HighlightGroupBoxLabel(QGroupBox *gb, QWidget *widget,
 
 void RestrictResetBitrates(initializer_list<QComboBox *> boxes, int maxbitrate);
 
-void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal,
-				  const char *slot)
-{
-	QObject::connect(widget, signal, this, slot);
-	widget->setProperty("changed", QVariant(false));
-}
-
 /* clang-format off */
-#define COMBO_CHANGED   SIGNAL(currentIndexChanged(int))
-#define EDIT_CHANGED    SIGNAL(textChanged(const QString &))
-#define CBEDIT_CHANGED  SIGNAL(editTextChanged(const QString &))
-#define CHECK_CHANGED   SIGNAL(clicked(bool))
-#define SCROLL_CHANGED  SIGNAL(valueChanged(int))
-#define DSCROLL_CHANGED SIGNAL(valueChanged(double))
-
-#define GENERAL_CHANGED SLOT(GeneralChanged())
-#define STREAM1_CHANGED SLOT(Stream1Changed())
-#define OUTPUTS_CHANGED SLOT(OutputsChanged())
-#define AUDIO_RESTART   SLOT(AudioChangedRestart())
-#define AUDIO_CHANGED   SLOT(AudioChanged())
-#define VIDEO_RES       SLOT(VideoChangedResolution())
-#define VIDEO_CHANGED   SLOT(VideoChanged())
-#define A11Y_CHANGED    SLOT(A11yChanged())
-#define ADV_CHANGED     SLOT(AdvancedChanged())
-#define ADV_RESTART     SLOT(AdvancedChangedRestart())
+#define COMBO_CHANGED   &QComboBox::currentIndexChanged
+#define EDIT_CHANGED    &QLineEdit::textChanged
+#define CBEDIT_CHANGED  &QComboBox::editTextChanged
+#define CHECK_CHANGED   &QCheckBox::clicked
+#define GROUP_CHANGED   &QGroupBox::clicked
+#define SCROLL_CHANGED  &QSpinBox::valueChanged
+#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
+
+#define GENERAL_CHANGED &OBSBasicSettings::GeneralChanged
+#define STREAM1_CHANGED &OBSBasicSettings::Stream1Changed
+#define OUTPUTS_CHANGED &OBSBasicSettings::OutputsChanged
+#define AUDIO_RESTART   &OBSBasicSettings::AudioChangedRestart
+#define AUDIO_CHANGED   &OBSBasicSettings::AudioChanged
+#define VIDEO_RES       &OBSBasicSettings::VideoChangedResolution
+#define VIDEO_CHANGED   &OBSBasicSettings::VideoChanged
+#define A11Y_CHANGED    &OBSBasicSettings::A11yChanged
+#define ADV_CHANGED     &OBSBasicSettings::AdvancedChanged
+#define ADV_RESTART     &OBSBasicSettings::AdvancedChangedRestart
 /* clang-format on */
 
 OBSBasicSettings::OBSBasicSettings(QWidget *parent)
@@ -596,7 +590,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	HookWidget(ui->fpsInteger,           SCROLL_CHANGED, VIDEO_CHANGED);
 	HookWidget(ui->fpsNumerator,         SCROLL_CHANGED, VIDEO_CHANGED);
 	HookWidget(ui->fpsDenominator,       SCROLL_CHANGED, VIDEO_CHANGED);
-	HookWidget(ui->colorsGroupBox,       CHECK_CHANGED,  A11Y_CHANGED);
+	HookWidget(ui->colorsGroupBox,       GROUP_CHANGED,  A11Y_CHANGED);
 	HookWidget(ui->colorPreset,          COMBO_CHANGED,  A11Y_CHANGED);
 	HookWidget(ui->renderer,             COMBO_CHANGED,  ADV_RESTART);
 	HookWidget(ui->adapter,              COMBO_CHANGED,  ADV_RESTART);
@@ -736,26 +730,26 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	ui->resetOSXVSync = nullptr;
 #endif
 
-	connect(ui->streamDelaySec, SIGNAL(valueChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->outputMode, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)),
-		this, SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(UpdateStreamDelayEstimate()));
+	connect(ui->streamDelaySec, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->outputMode, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->simpleOutputVBitrate, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->simpleOutputABitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack1Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack2Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack3Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack4Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack5Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(ui->advOutTrack6Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
 
 	//Apply button disabled until change.
 	EnableApplyButton(false);
@@ -815,78 +809,78 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	if (obs_audio_monitoring_available())
 		FillAudioMonitoringDevices();
 
-	connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SurroundWarning(int)));
-	connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SpeakerLayoutChanged(int)));
-	connect(ui->lowLatencyBuffering, SIGNAL(clicked(bool)), this,
-		SLOT(LowLatencyBufferingChanged(bool)));
-	connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleRecordingQualityChanged()));
-	connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleRecordingQualityLosslessWarning(int)));
-	connect(ui->simpleOutRecFormat, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleStreamingEncoderChanged()));
-	connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutRecEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutRecAEncoder, SIGNAL(currentIndexChanged(int)),
-		this, SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)),
-		this, SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleOutAdvanced, SIGNAL(toggled(bool)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->ignoreRecommended, SIGNAL(toggled(bool)), this,
-		SLOT(SimpleRecordingEncoderChanged()));
-	connect(ui->simpleReplayBuf, SIGNAL(toggled(bool)), this,
-		SLOT(SimpleReplayBufferChanged()));
-	connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this,
-		SLOT(SimpleReplayBufferChanged()));
-	connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)),
-		this, SLOT(SimpleReplayBufferChanged()));
-	connect(ui->simpleRBSecMax, SIGNAL(valueChanged(int)), this,
-		SLOT(SimpleReplayBufferChanged()));
-	connect(ui->advOutSplitFile, SIGNAL(stateChanged(int)), this,
-		SLOT(AdvOutSplitFileChanged()));
-	connect(ui->advOutSplitFileType, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvOutSplitFileChanged()));
-	connect(ui->advReplayBuf, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack1, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack2, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack3, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack4, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack5, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecTrack6, SIGNAL(toggled(bool)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecType, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advOutRecEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
-	connect(ui->advRBSecMax, SIGNAL(valueChanged(int)), this,
-		SLOT(AdvReplayBufferChanged()));
+	connect(ui->channelSetup, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SurroundWarning);
+	connect(ui->channelSetup, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SpeakerLayoutChanged);
+	connect(ui->lowLatencyBuffering, &QCheckBox::clicked, this,
+		&OBSBasicSettings::LowLatencyBufferingChanged);
+	connect(ui->simpleOutRecQuality, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingQualityChanged);
+	connect(ui->simpleOutRecQuality, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingQualityLosslessWarning);
+	connect(ui->simpleOutRecFormat, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutStrEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleStreamingEncoderChanged);
+	connect(ui->simpleOutStrEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutRecEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutRecAEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutputVBitrate, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutputABitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleOutAdvanced, &QCheckBox::toggled, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->ignoreRecommended, &QCheckBox::toggled, this,
+		&OBSBasicSettings::SimpleRecordingEncoderChanged);
+	connect(ui->simpleReplayBuf, &QCheckBox::toggled, this,
+		&OBSBasicSettings::SimpleReplayBufferChanged);
+	connect(ui->simpleOutputVBitrate, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::SimpleReplayBufferChanged);
+	connect(ui->simpleOutputABitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleReplayBufferChanged);
+	connect(ui->simpleRBSecMax, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::SimpleReplayBufferChanged);
+	connect(ui->advOutSplitFile, &QCheckBox::stateChanged, this,
+		&OBSBasicSettings::AdvOutSplitFileChanged);
+	connect(ui->advOutSplitFileType, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvOutSplitFileChanged);
+	connect(ui->advReplayBuf, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack1, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack2, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack3, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack4, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack5, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecTrack6, &QCheckBox::toggled, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack1Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack2Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack3Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack4Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack5Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutTrack6Bitrate, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecType, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advOutRecEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
+	connect(ui->advRBSecMax, &QSpinBox::valueChanged, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
 
 	// Get Bind to IP Addresses
 	obs_properties_t *ppts = obs_get_output_properties("rtmp_output");
@@ -967,26 +961,26 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 		QTStr("Basic.Settings.Output.Reconnect"));
 
 	// Add warning checks to advanced output recording section controls
-	connect(ui->advOutRecTrack1, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecTrack2, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecTrack3, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecTrack4, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecTrack5, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecTrack6, SIGNAL(clicked()), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvOutRecCheckWarnings()));
-	connect(ui->advOutRecAEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvOutRecCheckWarnings()));
+	connect(ui->advOutRecTrack1, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecTrack2, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecTrack3, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecTrack4, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecTrack5, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecTrack6, &QCheckBox::clicked, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecFormat, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
+	connect(ui->advOutRecEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvOutRecCheckWarnings);
 
 	// Check codec compatibility when format (container) changes
-	connect(ui->advOutRecFormat, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvOutRecCheckCodecs()));
+	connect(ui->advOutRecFormat, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvOutRecCheckCodecs);
 
 	// Set placeholder used when selection was reset due to incompatibilities
 	ui->advOutRecEncoder->setPlaceholderText(
@@ -1021,15 +1015,15 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
 	ui->advOutRecRescale->lineEdit()->setValidator(validator);
 	ui->advOutFFRescale->lineEdit()->setValidator(validator);
 
-	connect(ui->useStreamKeyAdv, SIGNAL(clicked()), this,
-		SLOT(UseStreamKeyAdvClicked()));
+	connect(ui->useStreamKeyAdv, &QCheckBox::clicked, this,
+		&OBSBasicSettings::UseStreamKeyAdvClicked);
 
-	connect(ui->simpleOutStrAEncoder, SIGNAL(currentIndexChanged(int)),
-		this, SLOT(SimpleStreamAudioEncoderChanged()));
-	connect(ui->advOutAEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvAudioEncodersChanged()));
-	connect(ui->advOutRecAEncoder, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(AdvAudioEncodersChanged()));
+	connect(ui->simpleOutStrAEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::SimpleStreamAudioEncoderChanged);
+	connect(ui->advOutAEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvAudioEncodersChanged);
+	connect(ui->advOutRecAEncoder, &QComboBox::currentIndexChanged, this,
+		&OBSBasicSettings::AdvAudioEncodersChanged);
 
 	UpdateAudioWarnings();
 	UpdateAdvNetworkGroup();
@@ -1431,8 +1425,8 @@ void OBSBasicSettings::LoadGeneralSettings()
 					"HideOBSWindowsFromCapture");
 		ui->hideOBSFromCapture->setChecked(hideWindowFromCapture);
 
-		connect(ui->hideOBSFromCapture, SIGNAL(stateChanged(int)), this,
-			SLOT(HideOBSWindowWarning(int)));
+		connect(ui->hideOBSFromCapture, &QCheckBox::stateChanged, this,
+			&OBSBasicSettings::HideOBSWindowWarning);
 	}
 #endif
 
@@ -2151,7 +2145,8 @@ OBSBasicSettings::CreateEncoderPropertyView(const char *encoder,
 	view->setFrameShape(QFrame::NoFrame);
 	view->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
 	view->setProperty("changed", QVariant(changed));
-	QObject::connect(view, SIGNAL(Changed()), this, SLOT(OutputsChanged()));
+	QObject::connect(view, &OBSPropertiesView::Changed, this,
+			 &OBSBasicSettings::OutputsChanged);
 
 	return view;
 }
@@ -2168,10 +2163,10 @@ void OBSBasicSettings::LoadAdvOutputStreamingEncoderProperties()
 					  QSizePolicy::Minimum);
 	ui->advOutEncoderLayout->addWidget(streamEncoderProps);
 
-	connect(streamEncoderProps, SIGNAL(Changed()), this,
-		SLOT(UpdateStreamDelayEstimate()));
-	connect(streamEncoderProps, SIGNAL(Changed()), this,
-		SLOT(AdvReplayBufferChanged()));
+	connect(streamEncoderProps, &OBSPropertiesView::Changed, this,
+		&OBSBasicSettings::UpdateStreamDelayEstimate);
+	connect(streamEncoderProps, &OBSPropertiesView::Changed, this,
+		&OBSBasicSettings::AdvReplayBufferChanged);
 
 	curAdvStreamEncoder = type;
 
@@ -2284,8 +2279,8 @@ void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties()
 						  QSizePolicy::Minimum);
 		ui->advOutRecEncoderProps->layout()->addWidget(
 			recordEncoderProps);
-		connect(recordEncoderProps, SIGNAL(Changed()), this,
-			SLOT(AdvReplayBufferChanged()));
+		connect(recordEncoderProps, &OBSPropertiesView::Changed, this,
+			&OBSBasicSettings::AdvReplayBufferChanged);
 	}
 
 	curAdvRecordEncoder = type;
@@ -4418,8 +4413,8 @@ void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx)
 						  QSizePolicy::Minimum);
 		ui->advOutRecEncoderProps->layout()->addWidget(
 			recordEncoderProps);
-		connect(recordEncoderProps, SIGNAL(Changed()), this,
-			SLOT(AdvReplayBufferChanged()));
+		connect(recordEncoderProps, &OBSPropertiesView::Changed, this,
+			&OBSBasicSettings::AdvReplayBufferChanged);
 	}
 
 	ui->advOutRecUseRescale->setVisible(true);

+ 9 - 1
UI/window-basic-settings.hpp

@@ -221,7 +221,15 @@ private:
 		EnableApplyButton(false);
 	}
 
-	void HookWidget(QWidget *widget, const char *signal, const char *slot);
+	template<typename Widget, typename WidgetParent, typename... SignalArgs,
+		 typename... SlotArgs>
+	void HookWidget(Widget *widget,
+			void (WidgetParent::*signal)(SignalArgs...),
+			void (OBSBasicSettings::*slot)(SlotArgs...))
+	{
+		QObject::connect(widget, signal, this, slot);
+		widget->setProperty("changed", QVariant(false));
+	}
 
 	bool QueryChanges();
 	bool QueryAllowedToClose();

+ 2 - 2
UI/window-basic-status-bar.cpp

@@ -67,8 +67,8 @@ void OBSBasicStatusBar::Activate()
 {
 	if (!active) {
 		refreshTimer = new QTimer(this);
-		connect(refreshTimer, SIGNAL(timeout()), this,
-			SLOT(UpdateStatusBar()));
+		connect(refreshTimer, &QTimer::timeout, this,
+			&OBSBasicStatusBar::UpdateStatusBar);
 
 		int skipped = video_output_get_skipped_frames(obs_get_video());
 		int total = video_output_get_total_frames(obs_get_video());

+ 3 - 1
UI/window-basic-status-bar.hpp

@@ -87,11 +87,13 @@ private:
 	static void OBSOutputReconnect(void *data, calldata_t *params);
 	static void OBSOutputReconnectSuccess(void *data, calldata_t *params);
 
+public slots:
+	void UpdateCPUUsage();
+
 private slots:
 	void Reconnect(int seconds);
 	void ReconnectSuccess();
 	void UpdateStatusBar();
-	void UpdateCPUUsage();
 	void UpdateCurrentFPS();
 	void UpdateIcons();
 

+ 31 - 23
UI/window-basic-transform.cpp

@@ -30,15 +30,9 @@ static OBSSceneItem FindASelectedItem(obs_scene_t *scene)
 	return item;
 }
 
-void OBSBasicTransform::HookWidget(QWidget *widget, const char *signal,
-				   const char *slot)
-{
-	QObject::connect(widget, signal, this, slot);
-}
-
-#define COMBO_CHANGED SIGNAL(currentIndexChanged(int))
-#define ISCROLL_CHANGED SIGNAL(valueChanged(int))
-#define DSCROLL_CHANGED SIGNAL(valueChanged(double))
+#define COMBO_CHANGED &QComboBox::currentIndexChanged
+#define ISCROLL_CHANGED &QSpinBox::valueChanged
+#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
 
 OBSBasicTransform::OBSBasicTransform(OBSSceneItem item, OBSBasic *parent)
 	: QDialog(parent),
@@ -49,20 +43,34 @@ OBSBasicTransform::OBSBasicTransform(OBSSceneItem item, OBSBasic *parent)
 
 	ui->setupUi(this);
 
-	HookWidget(ui->positionX, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->positionY, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->rotation, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->sizeX, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->sizeY, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->align, COMBO_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->boundsType, COMBO_CHANGED, SLOT(OnBoundsType(int)));
-	HookWidget(ui->boundsAlign, COMBO_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->boundsWidth, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->boundsHeight, DSCROLL_CHANGED, SLOT(OnControlChanged()));
-	HookWidget(ui->cropLeft, ISCROLL_CHANGED, SLOT(OnCropChanged()));
-	HookWidget(ui->cropRight, ISCROLL_CHANGED, SLOT(OnCropChanged()));
-	HookWidget(ui->cropTop, ISCROLL_CHANGED, SLOT(OnCropChanged()));
-	HookWidget(ui->cropBottom, ISCROLL_CHANGED, SLOT(OnCropChanged()));
+	HookWidget(ui->positionX, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->positionY, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->rotation, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->sizeX, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->sizeY, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->align, COMBO_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->boundsType, COMBO_CHANGED,
+		   &OBSBasicTransform::OnBoundsType);
+	HookWidget(ui->boundsAlign, COMBO_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->boundsWidth, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->boundsHeight, DSCROLL_CHANGED,
+		   &OBSBasicTransform::OnControlChanged);
+	HookWidget(ui->cropLeft, ISCROLL_CHANGED,
+		   &OBSBasicTransform::OnCropChanged);
+	HookWidget(ui->cropRight, ISCROLL_CHANGED,
+		   &OBSBasicTransform::OnCropChanged);
+	HookWidget(ui->cropTop, ISCROLL_CHANGED,
+		   &OBSBasicTransform::OnCropChanged);
+	HookWidget(ui->cropBottom, ISCROLL_CHANGED,
+		   &OBSBasicTransform::OnCropChanged);
 
 	ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
 

+ 8 - 1
UI/window-basic-transform.hpp

@@ -27,7 +27,14 @@ private:
 	bool ignoreTransformSignal = false;
 	bool ignoreItemChange = false;
 
-	void HookWidget(QWidget *widget, const char *signal, const char *slot);
+	template<typename Widget, typename WidgetParent, typename... SignalArgs,
+		 typename... SlotArgs>
+	void HookWidget(Widget *widget,
+			void (WidgetParent::*signal)(SignalArgs...),
+			void (OBSBasicTransform::*slot)(SlotArgs...))
+	{
+		QObject::connect(widget, signal, this, slot);
+	}
 
 	void SetScene(OBSScene scene);
 	void SetItem(OBSSceneItem newItem);

+ 2 - 2
UI/window-basic-vcam-config.cpp

@@ -31,8 +31,8 @@ OBSBasicVCamConfig::OBSBasicVCamConfig(const VCamConfig &_config,
 	ui->outputType->setCurrentIndex(
 		ui->outputType->findData((int)config.type));
 	OutputTypeChanged();
-	connect(ui->outputType, SIGNAL(currentIndexChanged(int)), this,
-		SLOT(OutputTypeChanged()));
+	connect(ui->outputType, &QComboBox::currentIndexChanged, this,
+		&OBSBasicVCamConfig::OutputTypeChanged);
 
 	connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
 		&OBSBasicVCamConfig::UpdateConfig);

+ 8 - 8
UI/window-importer.cpp

@@ -93,8 +93,8 @@ QWidget *ImporterEntryPathItemDelegate::createEditor(
 					QSizePolicy::ControlType::LineEdit));
 	layout->addWidget(text);
 
-	QObject::connect(text, SIGNAL(editingFinished()), this,
-			 SLOT(updateText()));
+	QObject::connect(text, &QLineEdit::editingFinished, this,
+			 &ImporterEntryPathItemDelegate::updateText);
 
 	QToolButton *browseButton = new QToolButton();
 	browseButton->setText("...");
@@ -419,8 +419,8 @@ OBSImporter::OBSImporter(QWidget *parent)
 	ui->tableView->horizontalHeader()->setSectionResizeMode(
 		ImporterColumn::Path, QHeaderView::ResizeMode::Stretch);
 
-	connect(optionsModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
-		this, SLOT(dataChanged()));
+	connect(optionsModel, &ImporterModel::dataChanged, this,
+		&OBSImporter::dataChanged);
 
 	ui->tableView->setEditTriggers(
 		QAbstractItemView::EditTrigger::CurrentChanged);
@@ -428,12 +428,12 @@ OBSImporter::OBSImporter(QWidget *parent)
 	ui->buttonBox->button(QDialogButtonBox::Ok)->setText(QTStr("Import"));
 	ui->buttonBox->button(QDialogButtonBox::Open)->setText(QTStr("Add"));
 
-	connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
-		this, SLOT(importCollections()));
+	connect(ui->buttonBox->button(QDialogButtonBox::Ok),
+		&QPushButton::clicked, this, &OBSImporter::importCollections);
 	connect(ui->buttonBox->button(QDialogButtonBox::Open),
-		SIGNAL(clicked()), this, SLOT(browseImport()));
+		&QPushButton::clicked, this, &OBSImporter::browseImport);
 	connect(ui->buttonBox->button(QDialogButtonBox::Close),
-		SIGNAL(clicked()), this, SLOT(close()));
+		&QPushButton::clicked, this, &OBSImporter::close);
 
 	ImportersInit();
 

+ 2 - 2
UI/window-missing-files.cpp

@@ -513,8 +513,8 @@ OBSMissingFiles::OBSMissingFiles(obs_missing_files_t *files, QWidget *parent)
 		&OBSMissingFiles::browseFolders);
 	connect(ui->cancelButton, &QPushButton::clicked, this,
 		&OBSMissingFiles::close);
-	connect(filesModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
-		SLOT(dataChanged()));
+	connect(filesModel, &MissingFilesModel::dataChanged, this,
+		&OBSMissingFiles::dataChanged);
 
 	QModelIndex index = filesModel->createIndex(0, 1);
 	QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex",

+ 11 - 10
UI/window-projector.cpp

@@ -61,7 +61,8 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
 	QAction *action = new QAction(this);
 	action->setShortcut(Qt::Key_Escape);
 	addAction(action);
-	connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
+	connect(action, &QAction::triggered, this,
+		&OBSProjector::EscapeTriggered);
 
 	setAttribute(Qt::WA_DeleteOnClose, true);
 
@@ -255,22 +256,21 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 	OBSQTDisplay::mousePressEvent(event);
 
 	if (event->button() == Qt::RightButton) {
-		OBSBasic *main =
-			reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
-		QMenu popup(this);
-
 		QMenu *projectorMenu = new QMenu(QTStr("Fullscreen"));
-		main->AddProjectorMenuMonitors(projectorMenu, this,
-					       SLOT(OpenFullScreenProjector()));
+		OBSBasic::AddProjectorMenuMonitors(
+			projectorMenu, this,
+			&OBSProjector::OpenFullScreenProjector);
+
+		QMenu popup(this);
 		popup.addMenu(projectorMenu);
 
 		if (GetMonitor() > -1) {
 			popup.addAction(QTStr("Windowed"), this,
-					SLOT(OpenWindowedProjector()));
+					&OBSProjector::OpenWindowedProjector);
 
 		} else if (!this->isMaximized()) {
 			popup.addAction(QTStr("ResizeProjectorWindowToContent"),
-					this, SLOT(ResizeToContent()));
+					this, &OBSProjector::ResizeToContent);
 		}
 
 		QAction *alwaysOnTopButton = new QAction(
@@ -283,7 +283,8 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 
 		popup.addAction(alwaysOnTopButton);
 
-		popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
+		popup.addAction(QTStr("Close"), this,
+				&OBSProjector::EscapeTriggered);
 		popup.exec(QCursor::pos());
 	} else if (event->button() == Qt::LeftButton) {
 		// Only MultiView projectors handle left click

+ 17 - 22
UI/window-remux.cpp

@@ -114,8 +114,8 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(
 				    QSizePolicy::ControlType::LineEdit));
 		layout->addWidget(text);
 
-		QObject::connect(text, SIGNAL(editingFinished()), this,
-				 SLOT(updateText()));
+		QObject::connect(text, &QLineEdit::editingFinished, this,
+				 &RemuxEntryPathItemDelegate::updateText);
 
 		QToolButton *browseButton = new QToolButton();
 		browseButton->setText("...");
@@ -700,35 +700,30 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_)
 		->setText(QTStr("Remux.ClearAll"));
 	ui->buttonBox->button(QDialogButtonBox::Reset)->setDisabled(true);
 
-	connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
-		this, SLOT(beginRemux()));
+	connect(ui->buttonBox->button(QDialogButtonBox::Ok),
+		&QPushButton::clicked, this, &OBSRemux::beginRemux);
 	connect(ui->buttonBox->button(QDialogButtonBox::Reset),
-		SIGNAL(clicked()), this, SLOT(clearFinished()));
+		&QPushButton::clicked, this, &OBSRemux::clearFinished);
 	connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults),
-		SIGNAL(clicked()), this, SLOT(clearAll()));
+		&QPushButton::clicked, this, &OBSRemux::clearAll);
 	connect(ui->buttonBox->button(QDialogButtonBox::Close),
-		SIGNAL(clicked()), this, SLOT(close()));
+		&QPushButton::clicked, this, &OBSRemux::close);
 
 	worker->moveToThread(&remuxer);
 	remuxer.start();
 
-	//gcc-4.8 can't use QPointer<RemuxWorker> below
-	RemuxWorker *worker_ = worker;
-	connect(worker_, &RemuxWorker::updateProgress, this,
+	connect(worker.data(), &RemuxWorker::updateProgress, this,
 		&OBSRemux::updateProgress);
-	connect(&remuxer, &QThread::finished, worker_, &QObject::deleteLater);
-	connect(worker_, &RemuxWorker::remuxFinished, this,
+	connect(&remuxer, &QThread::finished, worker.data(),
+		&QObject::deleteLater);
+	connect(worker.data(), &RemuxWorker::remuxFinished, this,
 		&OBSRemux::remuxFinished);
-	connect(this, &OBSRemux::remux, worker_, &RemuxWorker::remux);
+	connect(this, &OBSRemux::remux, worker.data(), &RemuxWorker::remux);
 
-	// Guessing the GCC bug mentioned above would also affect
-	// QPointer<RemuxQueueModel>? Unsure.
-	RemuxQueueModel *queueModel_ = queueModel;
-	connect(queueModel_,
-		SIGNAL(rowsInserted(const QModelIndex &, int, int)), this,
-		SLOT(rowCountChanged(const QModelIndex &, int, int)));
-	connect(queueModel_, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
-		this, SLOT(rowCountChanged(const QModelIndex &, int, int)));
+	connect(queueModel.data(), &RemuxQueueModel::rowsInserted, this,
+		&OBSRemux::rowCountChanged);
+	connect(queueModel.data(), &RemuxQueueModel::rowsRemoved, this,
+		&OBSRemux::rowCountChanged);
 
 	QModelIndex index = queueModel->createIndex(0, 1);
 	QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex",
@@ -945,7 +940,7 @@ void OBSRemux::remuxFinished(bool success)
 	queueModel->finishEntry(success);
 
 	if (autoRemux && autoRemuxFile != "") {
-		QTimer::singleShot(3000, this, SLOT(close()));
+		QTimer::singleShot(3000, this, &OBSRemux::close);
 
 		OBSBasic *main = OBSBasic::Get();
 		main->ShowStatusBarMessage(