Создание форм регистрации и авторизации на C++/Qt5

  Алексей Чистяков  | 

  |

  Обновл. 20 Июл 2021  | 

 28431

 ǀ   15 

За каждым клиентским приложением стоит система контроля и управления доступом. В этой статье описано создание приложения для авторизации и регистрации пользователей с использованием C++/Qt5. Создание приложения для авторизации состоит из 4 этапов:

   подготовка файлов приложения;

   разработка диалоговых окон;

   реализация классов;

   инициализация БД и интерфейса подключения к БД.

Приступим!

Этап №1: Подготовка файлов приложения

Начнем с создания нового проекта в Qt Creator. Для этого я воспользуюсь мастером создания новых проектов. В стартовом меню Qt Creator я выбираю "Новый проект" > "Приложение" > "Приложение QtWidgets":

Затем указываем имя, директорию и выбираем подходящий компилятор. В этом проекте уже будет заголовочный файл, форма и файл класса для главного окна MainWindow. Для регистрации, хранения и извлечения пользовательской информации нам потребуется база данных (БД). Для этого подключаем модуль QtSql в конфигурации проекта — файле, имеющем имя проекта и расширение .pro:

Чтобы работать с классами этого модуля, нам нужно подключить заголовочный метафайл.

Классы модуля QtSql делятся на 3 уровня:

   уровень драйверов — классы для получения данных на физическом уровне;

   программный уровень — программный интерфейс для обращения к базе данных;

   уровень пользовательского интерфейса — модели для отображения результатов запросов, представленные в форме вопросов-ответов.

Это приложение будет использовать классы второго уровня. Таким образом можно будет рассмотреть применение объектов класса QString для управления базой данных. Qt5 поддерживает следующие системы управления базами данных (СУБД):

Идентификатор Описание
QOCI БД Oracle v7,8,9
QODBC ODBC-сервер для Microsoft SQL Server, IBM DB2, Sybase SQL, iODBC и некоторых других
QMYSQL СУБД MySQL
QTDS Sybase Adaptive Server
QPSQL БД PostgreSQL с поддержкой SQL92/SQL3
QSQLITE SQLite v2
QSQLITE SQLite v3+
QIBASE Borland InterBase
QDB2 DB2 от IBM

Вы можете использовать идентификатор из этой таблицы для подключения к базе данных. Если вы не нашли здесь нужную СУБД, то вам придется самостоятельно написать для нее драйвер.

Наше приложение будет хранить свои данные локально, поэтому я воспользуюсь SQLite, так как драйвер этой СУБД и сама база по умолчанию всегда распространяются вместе с Qt5. Создаваемое приложение в своей работе будет оперировать тремя окнами:

   MainWindow — главное окно;

   auth_window — окно авторизации пользователя;

   reg_window — окно регистрации пользователя.

В проекте, созданном как "Приложение QtWidgets", по умолчанию создается окно MainWindow, ассоциированное с классом MainWindow.

Для реализации окон регистрации и авторизации добавим к проекту два новых класса формы QtDesigner. Для этого правой кнопкой мыши кликаем на папку проекта в «Обозревателе решений» и выбираем пункт "Добавить новый". Затем "Qt" > "Класс формы Qt Designer" и нажимаем на кнопку "Выбрать":

Теперь в нашем проекте есть все нужные нам файлы и модуль для работы с базой данных:


Этап №2: Разработка диалоговых окон


Перед реализацией классов нам нужно разработать внешний вид диалоговых окон. Закончив этот этап, возвращаться к нему больше не придется.

Идея нашего приложения следующая: положение и размер главного окна запоминаются для каждого авторизованного пользователя. Авторизация и регистрация происходят в отдельных окнах, принадлежащих главному окну. Соединение с базой данных также принадлежит главному окну.

Начнем с разработки окна авторизации. Для этого откройте в редакторе файл auth_window.ui:

Для начала подбираем размеры окна, воспользовавшись синими маркерами по периметру. Затем размещаем слой позиционирования Layout — просто перетаскиваем его из панели инструментов в наше окно. Для того, чтобы скомпоновать виджеты окна, как на вышеприведенном рисунке, нам нужно воспользоваться gridLayout (впрочем, вы можете справиться и без него).

Далее нужно разместить виджеты окна: кнопки, поля, ярлыки. Перетаскивайте их с панели инструментов в слой позиционирования. Каждый новый виджет будет перераспределять положение всех виджетов слоя. Как вы можете видеть, в этом окне используются виджеты QLabel, QLineEdit и QPushButton (не считая QGridLayout). Закончив размещать виджеты в окне, воспользуйтесь инструментом изменения порядка обхода (при использовании табуляции), кнопка для включения этого инструмента находится на панели сразу над областью редактирования:

Рекомендую называть виджеты в соответствии с их предназначением. Например, название loginPushButton явно говорит нам о назначении этого объекта, в отличие от lineEdit_2.

Вы можете изменить атрибуты виджетов, например, можно разместить надписи виджетов Qlabel по правому краю, изменив свойство QLabel.alignment:

Последний этап проектирования окна — это объявление слотов. Для этого вызовите контекстное меню виджета и выберите пункт "Перейти к слоту". В появившемся окне выбираем слот textEdited(QString) виджета QLineEdit:


Также нам потребуется слот clicked() виджета QAbstractButton:

Прототипы слотов будут созданы в заголовочном файле, а их реализация появится в файле auth_window.cpp. Разработка внешнего вида окна авторизации завершена.

Перейдем к разработке внешнего вида окна регистрации, для этого откройте файл reg_window.ui:

Повторите шаги, сделанные для предыдущего окна: подберите размер окна, разместите слой позиционирования, разместите виджеты в слое, дайте корректные имена созданным виджетам и создайте слоты textEdited(QString) для полей и clicked() для кнопки. Не забудьте расставить порядок перехода между виджетами при использовании табуляции.

Этап №3: Реализация классов

Все файлы и необходимые им слоты созданы, теперь можно приступить к описанию классов. Начинать реализацию классов лучше с объявления членов класса в заголовочном файле. Для реализации класса MainWindow понадобится подключить следующие заголовочные файлы:

   QMainWindow;

   QString;

   QtSql.

В файле mainwindow.h подключаем необходимые библиотеки и заголовочные файлы, а также необходимо подключить заголовочные файлы окон регистрации и авторизации:

Хотя Qt Creator поместил MainWindow по умолчанию в пространство имен Ui:

Не все функции класса будут сосредоточены на пользовательском интерфейсе. Так как я намерен вызывать главное окно лишь после успешной авторизации, мне понадобится создать public-метод display() для отображения главного окна. Для работы с базой данных мне понадобится public-метод connectDB(), а также экземпляр подключения к БД — mw_db, и строка для формирования запроса к БД — db_input.

Использование прочих членов класса MainWindow можно проследить в файле класса MainWindow.cpp:

Файл auth_window.h

Кроме автоматически созданных членов и слотов, классу окна авторизации понадобятся сигналы, которые окно авторизации будет посылать главному окну. Также понадобится пара переменных для хранения пользовательского ввода и геттеры для их получения:

Файл reg_window.h

Окну регистрации понадобится сигнал, который оно будет посылать главному окну, переменные для хранения пользовательского ввода и геттеры для них, а также я решил добавить функцию проверки пользователя на внимательность:

Файл auth_window.cpp

В автоматически созданных файлах класса содержимое конструкторов создается по умолчанию. В этом классе меня это устраивает:

В автоматически созданных слотах кнопок размещаю сигналы, объявленные в заголовочном файле:

В автоматически созданных слотах полей копирую содержимое полей в переменные класса:

Таким образом геттеры возвращают содержимое полей:

Файл reg_window.cpp

Конструктор и деструктор по умолчанию:

Слот кнопки регистрации вызывает сигнал для главного окна:

Слоты полей копируют пользовательский ввод:

Геттеры возвращают пользовательский ввод:

Функция checkPass() возвращает true, если пользователь не ошибся при подтверждении пароля в поле confirm:

Этап №4: Инициализация БД и интерфейса подключения к БД


На этом этапе мы работаем с файлом main_window.cpp. Первым делом нам нужно подключить файлы других классов с помощью директивы #include:

Модуль QtDebug используется для отображения ошибок программы в окне Qt Creator, вместо отображения в консоли или в виджете.

В конструкторе главного окна можно соединить сигналы со слотами и осуществить соединение с БД, а также создать в ней новую таблицу. Библиотека QtSql обеспечивает нам доступ к сообщениям с ошибками, которые формируются запросами QSqlQuery:

Функция authorizeUser() соединена с сигналом кнопки авторизации. Она сохраняет пользовательский ввод, составляет из него запрос к БД, проверяет хранимый пароль на соответствие тому, который ввел пользователь и, в случае успеха, открывает MainWindow с параметрами, сохраненными из предыдущей сессии:

Функция registerWindowShow() соединена с сигналом register_button_clicked(). Она скрывает окно авторизации и вызывает окно регистрации:

Функция registerUser() соединена с сигналом кнопки регистрации, расположенной в окне регистрации. Она выполняет проверку пользовательского ввода, получает новый номер записи из БД и регистрирует пользователя. Вы могли заметить, что у поля name при создании новой БД не было идентификатора unique, остальная часть программы тоже не выполняет проверки на уникальность регистрируемого имени:

Метод display() подменяет вызов главного окна вызовом окна авторизации:

Деструктор главного окна, в случае удачной авторизации, обновляет содержимое записи в БД и прерывает соединение с БД, а затем уничтожает окна приложения:

Функция connectDB() устанавливает имя БД и создает соединение с ней. После того, как эта функция будет выполнена впервые, в директории программы появится файл с именем, указанным здесь для базы данных:

Конечный результат работы нашего приложения авторизации/регистрации, написанного с помощью C++/Qt5:


Заключение

Теперь, если вы решите написать приложение, требующее авторизации пользователей, у вас есть пример того, как это можно сделать. В вашем приложении параметрами авторизации могут быть: голос, отпечатки пальцев, фото пользователя или что-то другое. Вы наверняка будете передавать пользовательский ввод для авторизации на удаленный сервер, обеспечите уникальность каждого имени и зашифруете канал связи. Уверен, что у вас всё получится!

Исходный код форм регистрации и авторизации на C++/Qt5.


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (25 оценок, среднее: 4,56 из 5)
Загрузка...

Комментариев: 15

  1. Владислав:

    Здраствуйте! Помогите пожалуйста. Когда я в окне регистрации регистрирую пользователя, он не попадает в базу данных и когда я в окне авторизации ввожу зарегестрированого пользователя то мне в консоле пишет:

    Password missmatch "" "".

    А сразу при запуске программы пишет:

    qt.core.qmetaobject.connectslotsbyname: QMetaObject::connectSlotsByName: No matching signal for on_LineEdit_testEdited(QString)
    qt.core.qmetaobject.connectslotsbyname: QMetaObject::connectSlotsByName: No matching signal for on_nameLineEdit_textEdited(QString)
    qt.core.qmetaobject.connectslotsbyname: QMetaObject::connectSlotsByName: No matching signal for on_passwordLineEdit_textEdited(QString)
    qt.core.qmetaobject.connectslotsbyname: QMetaObject::connectSlotsByName: No matching signal for on_confirmLineEdit_textEdited(QString)
    Unable to create a table QSqlError("1", "Unable to execute statement", "table userlist already exists")
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

    Как мне решить эту проблему? Буду очень благодарен за помощь.

    1. Finchi:

      Лучшим советом будет использование вывода сообщений в дебаггер на каждом этапе работы программы. Это самый легкий путь поиска ошибок.
      Так же изучите SQL запросы, чтобы были уверены что все делаете правильно. Вам в консоль пишет что вы создаете таблицу с уже существующим именем повторно. А так же ругается на сигналы QLineEdit

      1. Владислав:

        Спасибо!

  2. Владислав:

    Здраствуйте! У меня при нажатии кнопки регистрации окно регистрации не запускается а просто в концоле пишется user_counter(цифры).
    Как мне это исправить?

  3. Finchi:

    Для выполнения этого урока пришлось сперва выучить SQLite запросы, а затем вернуться 😉

    Реализовал все по-своему, в MSVS2022 Enterprise Edition + Qt6. Загрузить код сюда в удобной форме, чтобы он был вам полезен, уже не выйдет, поэтому вот ссылка на мой проект на GitHub —  Finchi’s project

    Все особенности реализации будут понятны из комментариев к коду.

    А тут напишу об особенностях построения проекта  в  Visual Studio:

    В отличии от Qt Creator файла проекта с расширением .pro у нас нет, поэтому базу данных нужно подключить еще на этапе создания проекта, кроме стандартных для Qt Widget Application модулей (Qt Core, Qt GUI, Qt Widgets) нужно подключить модуль Qt SQL

    Если проект уже создан, а модуль Qt SQL включить в него забыли, то можно это сделать кликнув правой клавишей по проекту в Обозревателе решений -> Свойства -> Qt Project Settings -> Qt Modules -> <Sellect Modules…> и тут выбрать Qt SQL

    Это, пожалуй,  единственное в чем нужно разобраться, чтобы сделать аналогичный проект в Visual Studio

  4. Юрий:

    Чтобы при запуске программы открывалось окно для ввода данных, нужно в main.cpp вместо

    написать

  5. Алексей:

    Вдогонку к своему комментарию от 23.12: в папке release проекта создать папку sqldrivers и поместить туда файл qsqlite.dll из папки C:\Qt\Qt5.10.1\5.10.1\mingw53_32\plugins\sqldrivers. Платформа windows7x64.

  6. Алексей:

    Здравствуйте! Проект компилируется, но тут же вылетает с ошибками:
    QSqlDatabase: QSQLITE driver not loaded
    QSqlDatabase: available drivers:
    Cannot open database: QSqlError("", "Driver not loaded", "Driver not loaded")
    Failed to connect DB
    QSqlQuery::exec: database not open
    Unable to create a table QSqlError("", "Driver not loaded", "Driver not loaded")
    QSqlDatabase: QSQLITE driver not loaded
    QSqlDatabase: available drivers:
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    Cannot open database: QSqlError("", "Driver not loaded", "Driver not loaded")

  7. Диметрианус:

    Всё работает! Большое Человеческое спасибо!

  8. s.vvardenfell:

    Для тех, у кого сначала запускается окно MainWindow до формы регистрации — необходимо в main убрать строку, вызывающую метод show() объекта MainWindow.
    Плюс создал объекты ui_Reg и ui_Auth в куче, ui_Auth->show() в конструкторе, все работает правильно.
    Большое спасибо автору за урок!

  9. Yulia:

    Здравствуйте. Подскажите как расставляется порядок появления окон? Если скопипастить весь код, выходит так что сначала открывается главная форма, а потом регистрация и вход.

  10. Артём:

    здравствуйте, сделал все по вашему алгоритму. При попытке запустить программу выдало много ошибок по типу "отсутствует QCored.dll(Qwidgetsd.dll)"и тд. Исправил путем копирования этих файлов из Qt папки в папку с программой, но теперь при запуске я вижу пустое окно mainwindow — больше ничего не происходит. Помогите пожалуйста

  11. Anton:

    здравствуйте, помогите разобраться, туплю, скопировал в один в один ваш проект попробовал с sqllite, все работает, но мне нужно что нибудь подобное на psql, и только я меняю значение addDatabase(QPSQL), приложение компилируется, запускается и сразу же вылетает, вот что пишет:

    QMetaObject::connectSlotsByName: No matching signal for on_lineEdit_textEdited(QString)
    Cannot open database: QSqlError("", "QPSQL: Unable to connect", "fe_sendauth: no password supplied\n")
    Failed to connect DB
    QSqlQuery::exec: database not open
    Unable to create a table QSqlError("", "", "")
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    Cannot open database: QSqlError("", "QPSQL: Unable to connect", "fe_sendauth: no password supplied\n")

  12. Виталий:

    Добрый день. В исходниках не оказалось mainwindow.ui файла.
    Не знаю задумано так или забыли.
    Спасибо за статью, очень полезная информация!

    1. Фото аватара Алексей Чистяков:

      Добрый день.
      Файл mainwindow.ui создаётся автоматически, если следовать этой инструкции. Он не содержит ничего, кроме автоматически созданной формы. До сих пор не было смысла его приводить.

Добавить комментарий для Юрий Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *