2. MySQL数据库连接与配置

任务目标

实现一个Qt Widgets程序,通过QSqlDatabase连接本机MySQL数据库,能够处理常见的连接失败场景(如服务未启动、密码错误、数据库不存在),并在界面上实时显示连接状态与错误信息。

环境准备

  • Qt 5.15+(含SQL模块)
  • MySQL 5.7/8.0 本机服务,创建测试库:CREATE DATABASE qt_test CHARACTER SET utf8mb4;
  • Qt安装目录需存在MySQL驱动:plugins/sqldrivers/libqsqlmysql.so(Linux/macOS)或qsqlmysql.dll(Windows)。若缺失,需用Qt源码中的mysql驱动插件自行编译,或安装libqt5sql-mysql(Linux)

关键完整代码

// main.cpp
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QSqlDatabase>
#include <QSqlError>
#include <QMessageBox>

class DbConnectWidget : public QWidget {
    Q_OBJECT
public:
    DbConnectWidget(QWidget *parent = nullptr) : QWidget(parent) {
        auto *form = new QFormLayout;
        hostEdit = new QLineEdit("127.0.0.1");
        portEdit = new QLineEdit("3306");
        userEdit = new QLineEdit("root");
        passEdit = new QLineEdit;
        passEdit->setEchoMode(QLineEdit::Password);
        dbEdit = new QLineEdit("qt_test");
        form->addRow("主机:", hostEdit);
        form->addRow("端口:", portEdit);
        form->addRow("用户:", userEdit);
        form->addRow("密码:", passEdit);
        form->addRow("数据库:", dbEdit);

        connectBtn = new QPushButton("连接");
        statusLabel = new QLabel("未连接");
        statusLabel->setWordWrap(true);

        auto *mainLayout = new QVBoxLayout(this);
        mainLayout->addLayout(form);
        mainLayout->addWidget(connectBtn);
        mainLayout->addWidget(statusLabel);

        connect(connectBtn, &QPushButton::clicked, this, &DbConnectWidget::tryConnect);
    }

private slots:
    void tryConnect() {
        // 先清理旧连接,避免重复连接时名称冲突
        if (QSqlDatabase::contains("main_conn")) {
            QSqlDatabase::removeDatabase("main_conn");
        }
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "main_conn");
        db.setHostName(hostEdit->text().trimmed());
        db.setPort(portEdit->text().toInt());
        db.setUserName(userEdit->text().trimmed());
        db.setPassword(passEdit->text());
        db.setDatabaseName(dbEdit->text().trimmed());

        if (!db.open()) {
            QSqlError err = db.lastError();
            QString detail = err.databaseText();
            if (detail.isEmpty())
                detail = err.driverText();
            statusLabel->setText("连接失败: " + detail);
            statusLabel->setStyleSheet("color: #c0392b;");
            return;
        }
        statusLabel->setText("连接成功!数据库版本: " + db.driverName());
        statusLabel->setStyleSheet("color: #27ae60;");
        db.close();
    }

private:
    QLineEdit *hostEdit, *portEdit, *userEdit, *passEdit, *dbEdit;
    QPushButton *connectBtn;
    QLabel *statusLabel;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    DbConnectWidget w;
    w.setWindowTitle("MySQL连接测试");
    w.resize(360, 220);
    w.show();
    return app.exec();
}
#include "main.moc"

工程文件(.pro)

QT += widgets sql
SOURCES = main.cpp
TARGET = mysql_connect

运行与验证

  1. 编译:qmake && make(Linux/macOS)或使用Qt Creator直接构建。
  2. 启动MySQL服务,确保qt_test库存在。
  3. 运行程序,默认参数指向本机root用户。点击“连接”,观察状态标签:
测试场景预期显示
MySQL正常,密码正确绿色“连接成功!数据库版本: QMYSQL”
MySQL未启动或端口错误红色“连接失败: Unknown MySQL server host ...”或“Connection refused”
密码错误红色“连接失败: Access denied for user ...”
数据库名不存在红色“连接失败: Unknown database 'xxx'”

通过条件:上述四种场景均能显示对应的明确错误信息,且程序不崩溃;连接成功后状态标签变绿。

关键说明

  • 每次点击连接前先removeDatabase,避免重复添加同名连接导致警告。
  • 若提示QSqlDatabase: QMYSQL driver not loaded,说明Qt缺少MySQL驱动插件,需先解决驱动问题再运行本程序。
  • 错误信息优先取databaseText(),为空时回退到driverText(),以覆盖MySQL服务端错误与客户端驱动错误两种来源。