diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h
index 1cd2e51b26..747c46c204 100644
--- a/src/core/hle/service/acc/profile_manager.h
+++ b/src/core/hle/service/acc/profile_manager.h
@@ -57,7 +57,8 @@ struct UUID {
 };
 static_assert(sizeof(UUID) == 16, "UUID is an invalid size!");
 
-using ProfileUsername = std::array<u8, 0x20>;
+constexpr std::size_t profile_username_size = 32;
+using ProfileUsername = std::array<u8, profile_username_size>;
 using ProfileData = std::array<u8, MAX_DATA>;
 using UserIDArray = std::array<UUID, MAX_USERS>;
 
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 9379d9110f..f9ca2948ee 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -56,6 +56,8 @@ add_executable(yuzu
     main.h
     ui_settings.cpp
     ui_settings.h
+    util/limitable_input_dialog.cpp
+    util/limitable_input_dialog.h
     util/spinbox.cpp
     util/spinbox.h
     util/util.cpp
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 4b34c1e28a..a9dbcd71b2 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -6,20 +6,20 @@
 #include <QFileDialog>
 #include <QGraphicsItem>
 #include <QGraphicsScene>
-#include <QInputDialog>
+#include <QHeaderView>
 #include <QMessageBox>
 #include <QStandardItemModel>
 #include <QTreeView>
 #include <QVBoxLayout>
-#include "common/common_paths.h"
-#include "common/logging/backend.h"
+#include "common/assert.h"
+#include "common/file_util.h"
 #include "common/string_util.h"
 #include "core/core.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/settings.h"
 #include "ui_configure_system.h"
 #include "yuzu/configuration/configure_system.h"
-#include "yuzu/main.h"
+#include "yuzu/util/limitable_input_dialog.h"
 
 namespace {
 constexpr std::array<int, 12> days_in_month = {{
@@ -83,6 +83,12 @@ QPixmap GetIcon(Service::Account::UUID uuid) {
 
     return icon.scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
 }
+
+QString GetProfileUsernameFromUser(QWidget* parent, const QString& description_text) {
+    return LimitableInputDialog::GetText(parent, ConfigureSystem::tr("Enter Username"),
+                                         description_text, 1,
+                                         static_cast<int>(Service::Account::profile_username_size));
+}
 } // Anonymous namespace
 
 ConfigureSystem::ConfigureSystem(QWidget* parent)
@@ -244,15 +250,13 @@ void ConfigureSystem::SelectUser(const QModelIndex& index) {
 }
 
 void ConfigureSystem::AddUser() {
-    const auto uuid = Service::Account::UUID::Generate();
-
-    bool ok = false;
     const auto username =
-        QInputDialog::getText(this, tr("Enter Username"), tr("Enter a username for the new user:"),
-                              QLineEdit::Normal, QString(), &ok);
-    if (!ok)
+        GetProfileUsernameFromUser(this, tr("Enter a username for the new user:"));
+    if (username.isEmpty()) {
         return;
+    }
 
+    const auto uuid = Service::Account::UUID::Generate();
     profile_manager->CreateNewUser(uuid, username.toStdString());
 
     item_model->appendRow(new QStandardItem{GetIcon(uuid), FormatUserEntryText(username, uuid)});
@@ -267,24 +271,15 @@ void ConfigureSystem::RenameUser() {
     if (!profile_manager->GetProfileBase(*uuid, profile))
         return;
 
-    bool ok = false;
-    const auto old_username = GetAccountUsername(*profile_manager, *uuid);
-    const auto new_username =
-        QInputDialog::getText(this, tr("Enter Username"), tr("Enter a new username:"),
-                              QLineEdit::Normal, old_username, &ok);
-
-    if (!ok)
+    const auto new_username = GetProfileUsernameFromUser(this, tr("Enter a new username:"));
+    if (new_username.isEmpty()) {
         return;
-
-    std::fill(profile.username.begin(), profile.username.end(), '\0');
-    const auto username_std = new_username.toStdString();
-    if (username_std.size() > profile.username.size()) {
-        std::copy_n(username_std.begin(), std::min(profile.username.size(), username_std.size()),
-                    profile.username.begin());
-    } else {
-        std::copy(username_std.begin(), username_std.end(), profile.username.begin());
     }
 
+    const auto username_std = new_username.toStdString();
+    std::fill(profile.username.begin(), profile.username.end(), '\0');
+    std::copy(username_std.begin(), username_std.end(), profile.username.begin());
+
     profile_manager->SetProfileBase(*uuid, profile);
 
     item_model->setItem(
diff --git a/src/yuzu/util/limitable_input_dialog.cpp b/src/yuzu/util/limitable_input_dialog.cpp
new file mode 100644
index 0000000000..edd78e5793
--- /dev/null
+++ b/src/yuzu/util/limitable_input_dialog.cpp
@@ -0,0 +1,59 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include "yuzu/util/limitable_input_dialog.h"
+
+LimitableInputDialog::LimitableInputDialog(QWidget* parent) : QDialog{parent} {
+    CreateUI();
+    ConnectEvents();
+}
+
+LimitableInputDialog::~LimitableInputDialog() = default;
+
+void LimitableInputDialog::CreateUI() {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+    text_label = new QLabel(this);
+    text_entry = new QLineEdit(this);
+    buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+
+    auto* const layout = new QVBoxLayout;
+    layout->addWidget(text_label);
+    layout->addWidget(text_entry);
+    layout->addWidget(buttons);
+
+    setLayout(layout);
+}
+
+void LimitableInputDialog::ConnectEvents() {
+    connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
+    connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
+}
+
+QString LimitableInputDialog::GetText(QWidget* parent, const QString& title, const QString& text,
+                                      int min_character_limit, int max_character_limit) {
+    Q_ASSERT(min_character_limit <= max_character_limit);
+
+    LimitableInputDialog dialog{parent};
+    dialog.setWindowTitle(title);
+    dialog.text_label->setText(text);
+    dialog.text_entry->setMaxLength(max_character_limit);
+
+    auto* const ok_button = dialog.buttons->button(QDialogButtonBox::Ok);
+    ok_button->setEnabled(false);
+    connect(dialog.text_entry, &QLineEdit::textEdited, [&](const QString& new_text) {
+        ok_button->setEnabled(new_text.length() >= min_character_limit);
+    });
+
+    if (dialog.exec() != QDialog::Accepted) {
+        return {};
+    }
+
+    return dialog.text_entry->text();
+}
diff --git a/src/yuzu/util/limitable_input_dialog.h b/src/yuzu/util/limitable_input_dialog.h
new file mode 100644
index 0000000000..164ad73019
--- /dev/null
+++ b/src/yuzu/util/limitable_input_dialog.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QDialog>
+
+class QDialogButtonBox;
+class QLabel;
+class QLineEdit;
+
+/// A QDialog that functions similarly to QInputDialog, however, it allows
+/// restricting the minimum and total number of characters that can be entered.
+class LimitableInputDialog final : public QDialog {
+    Q_OBJECT
+public:
+    explicit LimitableInputDialog(QWidget* parent = nullptr);
+    ~LimitableInputDialog() override;
+
+    static QString GetText(QWidget* parent, const QString& title, const QString& text,
+                           int min_character_limit, int max_character_limit);
+
+private:
+    void CreateUI();
+    void ConnectEvents();
+
+    QLabel* text_label;
+    QLineEdit* text_entry;
+    QDialogButtonBox* buttons;
+};