diff --git a/src/core/analog_controller.cpp b/src/core/analog_controller.cpp
index b745386e3..76038d77c 100644
--- a/src/core/analog_controller.cpp
+++ b/src/core/analog_controller.cpp
@@ -466,25 +466,31 @@ std::optional<s32> AnalogController::StaticGetButtonCodeByName(std::string_view
 
 Controller::AxisList AnalogController::StaticGetAxisNames()
 {
-#define A(n)                                                                                                           \
-  {                                                                                                                    \
-#n, static_cast < s32>(Axis::n)                                                                                    \
-  }
-
-  return {A(LeftX), A(LeftY), A(RightX), A(RightY)};
-
-#undef A
+  return {{TRANSLATABLE("AnalogController", "LeftX"), static_cast<s32>(Axis::LeftX)},
+          {TRANSLATABLE("AnalogController", "LeftY"), static_cast<s32>(Axis::LeftY)},
+          {TRANSLATABLE("AnalogController", "RightX"), static_cast<s32>(Axis::RightX)},
+          {TRANSLATABLE("AnalogController", "RightY"), static_cast<s32>(Axis::RightY)}};
 }
 
 Controller::ButtonList AnalogController::StaticGetButtonNames()
 {
-#define B(n)                                                                                                           \
-  {                                                                                                                    \
-#n, static_cast < s32>(Button::n)                                                                                  \
-  }
-  return {B(Up),     B(Down), B(Left), B(Right), B(Select), B(Start), B(Triangle), B(Cross), B(Circle),
-          B(Square), B(L1),   B(L2),   B(R1),    B(R2),     B(L3),    B(R3),       B(Analog)};
-#undef B
+  return {{TRANSLATABLE("AnalogController", "Up"), static_cast<s32>(Button::Up)},
+          {TRANSLATABLE("AnalogController", "Down"), static_cast<s32>(Button::Down)},
+          {TRANSLATABLE("AnalogController", "Left"), static_cast<s32>(Button::Left)},
+          {TRANSLATABLE("AnalogController", "Right"), static_cast<s32>(Button::Right)},
+          {TRANSLATABLE("AnalogController", "Select"), static_cast<s32>(Button::Select)},
+          {TRANSLATABLE("AnalogController", "Start"), static_cast<s32>(Button::Start)},
+          {TRANSLATABLE("AnalogController", "Triangle"), static_cast<s32>(Button::Triangle)},
+          {TRANSLATABLE("AnalogController", "Cross"), static_cast<s32>(Button::Cross)},
+          {TRANSLATABLE("AnalogController", "Circle"), static_cast<s32>(Button::Circle)},
+          {TRANSLATABLE("AnalogController", "Square"), static_cast<s32>(Button::Square)},
+          {TRANSLATABLE("AnalogController", "L1"), static_cast<s32>(Button::L1)},
+          {TRANSLATABLE("AnalogController", "L2"), static_cast<s32>(Button::L2)},
+          {TRANSLATABLE("AnalogController", "R1"), static_cast<s32>(Button::R1)},
+          {TRANSLATABLE("AnalogController", "R2"), static_cast<s32>(Button::R2)},
+          {TRANSLATABLE("AnalogController", "L3"), static_cast<s32>(Button::L3)},
+          {TRANSLATABLE("AnalogController", "R3"), static_cast<s32>(Button::R3)},
+          {TRANSLATABLE("AnalogController", "Analog"), static_cast<s32>(Button::Analog)}};
 }
 
 u32 AnalogController::StaticGetVibrationMotorCount()
@@ -495,11 +501,14 @@ u32 AnalogController::StaticGetVibrationMotorCount()
 Controller::SettingList AnalogController::StaticGetSettings()
 {
   static constexpr std::array<SettingInfo, 2> settings = {
-    {{SettingInfo::Type::Boolean, "AutoEnableAnalog", "Enable Analog Mode on Reset",
-      "Automatically enables analog mode when the console is reset/powered on.", "false"},
-     {SettingInfo::Type::Float, "AxisScale", "Analog Axis Scale",
-      "Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
-      "controllers, e.g. DualShock 4, Xbox One Controller.",
+    {{SettingInfo::Type::Boolean, "AutoEnableAnalog", TRANSLATABLE("AnalogController", "Enable Analog Mode on Reset"),
+      TRANSLATABLE("AnalogController", "Automatically enables analog mode when the console is reset/powered on."),
+      "false"},
+     {SettingInfo::Type::Float, "AxisScale", TRANSLATABLE("AnalogController", "Analog Axis Scale"),
+      TRANSLATABLE(
+        "AnalogController",
+        "Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
+        "controllers, e.g. DualShock 4, Xbox One Controller."),
       "1.00f", "0.01f", "1.50f", "0.01f"}}};
 
   return SettingList(settings.begin(), settings.end());
diff --git a/src/core/digital_controller.cpp b/src/core/digital_controller.cpp
index 5444356e2..8ab5d7bbc 100644
--- a/src/core/digital_controller.cpp
+++ b/src/core/digital_controller.cpp
@@ -1,6 +1,7 @@
 #include "digital_controller.h"
 #include "common/assert.h"
 #include "common/state_wrapper.h"
+#include "host_interface.h"
 
 DigitalController::DigitalController() = default;
 
@@ -155,13 +156,20 @@ Controller::AxisList DigitalController::StaticGetAxisNames()
 
 Controller::ButtonList DigitalController::StaticGetButtonNames()
 {
-#define B(n)                                                                                                           \
-  {                                                                                                                    \
-#n, static_cast < s32>(Button::n)                                                                                  \
-  }
-  return {B(Up),    B(Down),   B(Left),   B(Right), B(Select), B(Start), B(Triangle),
-          B(Cross), B(Circle), B(Square), B(L1),    B(L2),     B(R1),    B(R2)};
-#undef B
+  return {{TRANSLATABLE("DigitalController", "Up"), static_cast<s32>(Button::Up)},
+          {TRANSLATABLE("DigitalController", "Down"), static_cast<s32>(Button::Down)},
+          {TRANSLATABLE("DigitalController", "Left"), static_cast<s32>(Button::Left)},
+          {TRANSLATABLE("DigitalController", "Right"), static_cast<s32>(Button::Right)},
+          {TRANSLATABLE("DigitalController", "Select"), static_cast<s32>(Button::Select)},
+          {TRANSLATABLE("DigitalController", "Start"), static_cast<s32>(Button::Start)},
+          {TRANSLATABLE("DigitalController", "Triangle"), static_cast<s32>(Button::Triangle)},
+          {TRANSLATABLE("DigitalController", "Cross"), static_cast<s32>(Button::Cross)},
+          {TRANSLATABLE("DigitalController", "Circle"), static_cast<s32>(Button::Circle)},
+          {TRANSLATABLE("DigitalController", "Square"), static_cast<s32>(Button::Square)},
+          {TRANSLATABLE("DigitalController", "L1"), static_cast<s32>(Button::L1)},
+          {TRANSLATABLE("DigitalController", "L2"), static_cast<s32>(Button::L2)},
+          {TRANSLATABLE("DigitalController", "R1"), static_cast<s32>(Button::R1)},
+          {TRANSLATABLE("DigitalController", "R2"), static_cast<s32>(Button::R2)}};
 }
 
 u32 DigitalController::StaticGetVibrationMotorCount()
diff --git a/src/core/namco_guncon.cpp b/src/core/namco_guncon.cpp
index 8916c5282..b3bf49488 100644
--- a/src/core/namco_guncon.cpp
+++ b/src/core/namco_guncon.cpp
@@ -209,12 +209,9 @@ Controller::AxisList NamcoGunCon::StaticGetAxisNames()
 
 Controller::ButtonList NamcoGunCon::StaticGetButtonNames()
 {
-#define B(n)                                                                                                           \
-  {                                                                                                                    \
-#n, static_cast < s32>(Button::n)                                                                                  \
-  }
-  return {B(Trigger), B(A), B(B)};
-#undef B
+  return {{TRANSLATABLE("NamcoGunCon", "Trigger"), static_cast<s32>(Button::Trigger)},
+          {TRANSLATABLE("NamcoGunCon", "A"), static_cast<s32>(Button::A)},
+          {TRANSLATABLE("NamcoGunCon", "B"), static_cast<s32>(Button::B)}};
 }
 
 u32 NamcoGunCon::StaticGetVibrationMotorCount()
diff --git a/src/duckstation-qt/controllersettingswidget.cpp b/src/duckstation-qt/controllersettingswidget.cpp
index c7c5d7914..76783c03f 100644
--- a/src/duckstation-qt/controllersettingswidget.cpp
+++ b/src/duckstation-qt/controllersettingswidget.cpp
@@ -174,6 +174,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
 
   QGridLayout* layout = new QGridLayout(ui->bindings_container);
   const auto buttons = Controller::GetButtonNames(ctype);
+  const char* cname = Settings::GetControllerTypeName(ctype);
 
   InputBindingWidget* first_button = nullptr;
   InputBindingWidget* last_button = nullptr;
@@ -196,7 +197,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
 
       std::string section_name = StringUtil::StdStringFromFormat("Controller%d", index + 1);
       std::string key_name = StringUtil::StdStringFromFormat("Button%s", button_name.c_str());
-      QLabel* label = new QLabel(QString::fromStdString(button_name), ui->bindings_container);
+      QLabel* label = new QLabel(qApp->translate(cname, button_name.c_str()), ui->bindings_container);
       InputButtonBindingWidget* button = new InputButtonBindingWidget(m_host_interface, std::move(section_name),
                                                                       std::move(key_name), ui->bindings_container);
       layout->addWidget(label, start_row + current_row, current_column);
@@ -233,7 +234,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
 
       std::string section_name = StringUtil::StdStringFromFormat("Controller%d", index + 1);
       std::string key_name = StringUtil::StdStringFromFormat("Axis%s", axis_name.c_str());
-      QLabel* label = new QLabel(QString::fromStdString(axis_name), ui->bindings_container);
+      QLabel* label = new QLabel(qApp->translate(cname, axis_name.c_str()), ui->bindings_container);
       InputAxisBindingWidget* button = new InputAxisBindingWidget(m_host_interface, std::move(section_name),
                                                                   std::move(key_name), ui->bindings_container);
       layout->addWidget(label, start_row + current_row, current_column);
@@ -282,13 +283,13 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
     {
       std::string section_name = StringUtil::StdStringFromFormat("Controller%d", index + 1);
       std::string key_name = si.key;
-      const QString setting_tooltip = si.description ? QString::fromUtf8(si.description) : "";
+      const QString setting_tooltip = si.description ? qApp->translate(cname, si.description) : QString();
 
       switch (si.type)
       {
         case SettingInfo::Type::Boolean:
         {
-          QCheckBox* cb = new QCheckBox(tr(si.visible_name), ui->bindings_container);
+          QCheckBox* cb = new QCheckBox(qApp->translate(cname, si.visible_name), ui->bindings_container);
           cb->setToolTip(setting_tooltip);
           SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, cb, std::move(section_name),
                                                        std::move(key_name), si.BooleanDefaultValue());
@@ -306,7 +307,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
           sb->setSingleStep(si.IntegerStepValue());
           SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, sb, std::move(section_name),
                                                       std::move(key_name), si.IntegerDefaultValue());
-          layout->addWidget(new QLabel(tr(si.visible_name), ui->bindings_container), start_row, 0);
+          layout->addWidget(new QLabel(qApp->translate(cname, si.visible_name), ui->bindings_container), start_row, 0);
           layout->addWidget(sb, start_row, 1, 1, 3);
           start_row++;
         }
@@ -321,7 +322,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
           sb->setSingleStep(si.FloatStepValue());
           SettingWidgetBinder::BindWidgetToFloatSetting(m_host_interface, sb, std::move(section_name),
                                                         std::move(key_name), si.FloatDefaultValue());
-          layout->addWidget(new QLabel(tr(si.visible_name), ui->bindings_container), start_row, 0);
+          layout->addWidget(new QLabel(qApp->translate(cname, si.visible_name), ui->bindings_container), start_row, 0);
           layout->addWidget(sb, start_row, 1, 1, 3);
           start_row++;
         }
@@ -333,7 +334,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
           le->setToolTip(setting_tooltip);
           SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, le, std::move(section_name),
                                                          std::move(key_name), si.StringDefaultValue());
-          layout->addWidget(new QLabel(tr(si.visible_name), ui->bindings_container), start_row, 0);
+          layout->addWidget(new QLabel(qApp->translate(cname, si.visible_name), ui->bindings_container), start_row, 0);
           layout->addWidget(le, start_row, 1, 1, 3);
           start_row++;
         }
@@ -356,7 +357,7 @@ void ControllerSettingsWidget::createPortBindingSettingsUi(int index, PortSettin
           hbox->addWidget(le, 1);
           hbox->addWidget(browse_button);
 
-          layout->addWidget(new QLabel(tr(si.visible_name), ui->bindings_container), start_row, 0);
+          layout->addWidget(new QLabel(qApp->translate(cname, si.visible_name), ui->bindings_container), start_row, 0);
           layout->addLayout(hbox, start_row, 1, 1, 3);
           start_row++;
         }
diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp
index 97e67ef50..e28c7d6ad 100644
--- a/src/duckstation-qt/mainwindow.cpp
+++ b/src/duckstation-qt/mainwindow.cpp
@@ -27,10 +27,11 @@
 #include <QtWidgets/QStyleFactory>
 #include <cmath>
 
-static constexpr char DISC_IMAGE_FILTER[] =
+static constexpr char DISC_IMAGE_FILTER[] = QT_TRANSLATE_NOOP(
+  "MainWindow",
   "All File Types (*.bin *.img *.cue *.chd *.exe *.psexe *.psf);;Single-Track Raw Images (*.bin *.img);;Cue Sheets "
   "(*.cue);;MAME CHD Images (*.chd);;PlayStation Executables (*.exe *.psexe);;Portable Sound Format Files "
-  "(*.psf);;Playlists (*.m3u)";
+  "(*.psf);;Playlists (*.m3u)");
 
 ALWAYS_INLINE static QString getWindowTitle()
 {
diff --git a/src/duckstation-qt/memorycardsettingswidget.cpp b/src/duckstation-qt/memorycardsettingswidget.cpp
index 63ee1eaae..6df775b40 100644
--- a/src/duckstation-qt/memorycardsettingswidget.cpp
+++ b/src/duckstation-qt/memorycardsettingswidget.cpp
@@ -11,7 +11,7 @@
 #include <QtWidgets/QFileDialog>
 #include <QtWidgets/QLabel>
 
-static constexpr char MEMORY_CARD_IMAGE_FILTER[] = "All Memory Card Types (*.mcd *.mcr *.mc)";
+static constexpr char MEMORY_CARD_IMAGE_FILTER[] = QT_TRANSLATE_NOOP("MemoryCardSettingsWidget", "All Memory Card Types (*.mcd *.mcr *.mc)");
 
 MemoryCardSettingsWidget::MemoryCardSettingsWidget(QtHostInterface* host_interface, QWidget* parent,
                                                    SettingsDialog* dialog)