修复数据库切换连接异常问题

This commit is contained in:
taocong
2026-09-17 08:49:06 +08:00
committed by taocong45644
parent 903d805f31
commit 14880cc6ad
11 changed files with 372 additions and 245 deletions
+3 -2
View File
@@ -20,9 +20,10 @@ int main(int argc, char *argv[])
QCoreApplication::addLibraryPath(basePath); QCoreApplication::addLibraryPath(basePath);
QCoreApplication::addLibraryPath(basePath + "/sqldrivers"); QCoreApplication::addLibraryPath(basePath + "/sqldrivers");
ConfigManager::instance()->loadConfig(basePath); // 配置文件位于 程序目录/config/config.ini(loadConfig 内部使用 appConfigDir())
ConfigManager::instance()->loadConfig();
MainWindow w; MainWindow w;
w.show(); w.showMaximized();
return a.exec(); return a.exec();
} }
+10 -9
View File
@@ -5,6 +5,7 @@
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QSqlQuery> #include <QSqlQuery>
#include <QSettings> #include <QSettings>
#include "utils/configmanager.h"
// 连接参数结构体 // 连接参数结构体
struct ConnectionParams { struct ConnectionParams {
@@ -18,15 +19,15 @@ struct ConnectionParams {
// 从 QSettings group 加载 // 从 QSettings group 加载
static ConnectionParams fromSettings(const QString& connectionKey) { static ConnectionParams fromSettings(const QString& connectionKey) {
ConnectionParams p; ConnectionParams p;
QSettings settings("Omnitool", "DatabaseConnections"); QSettings* settings = appConnectionsSettings();
settings.beginGroup(connectionKey); settings->beginGroup(connectionKey);
p.dbType = settings.value("dbType", "MySQL").toString(); p.dbType = settings->value("dbType", "MySQL").toString();
p.host = settings.value("host").toString(); p.host = settings->value("host").toString();
p.port = settings.value("port").toString(); p.port = settings->value("port").toString();
p.database = settings.value("database").toString(); p.database = settings->value("database").toString();
p.username = settings.value("username").toString(); p.username = settings->value("username").toString();
p.password = settings.value("password").toString(); p.password = settings->value("password").toString();
settings.endGroup(); settings->endGroup();
return p; return p;
} }
}; };
+36 -7
View File
@@ -9,11 +9,14 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QShowEvent>
#include <QSettings> #include <QSettings>
#include <QMessageBox> #include <QMessageBox>
#include <QLabel> #include <QLabel>
#include <QDateTime> #include <QDateTime>
#include <QDir>
#include "utils/logmanager.h" #include "utils/logmanager.h"
#include "utils/configmanager.h"
DatabaseConnectionConfigDialog::DatabaseConnectionConfigDialog(QWidget* parent) DatabaseConnectionConfigDialog::DatabaseConnectionConfigDialog(QWidget* parent)
: QDialog(parent) : QDialog(parent)
{ {
@@ -121,7 +124,7 @@ void DatabaseConnectionConfigDialog::loadConnections()
{ {
_connectionTable->setRowCount(0); _connectionTable->setRowCount(0);
QSettings settings("Omnitool", "DatabaseConnections"); QSettings settings(QDir(appConfigDir()).filePath("config.ini"), QSettings::IniFormat);
QStringList groups = settings.childGroups(); QStringList groups = settings.childGroups();
for (const QString& group : groups) { for (const QString& group : groups) {
@@ -231,13 +234,34 @@ void DatabaseConnectionConfigDialog::loadConnections()
_connectionTable->setCellWidget(0, 0, emptyWidget); _connectionTable->setCellWidget(0, 0, emptyWidget);
} }
resizeTableColumns();
}
void DatabaseConnectionConfigDialog::resizeTableColumns()
{
if (!_connectionTable) return;
// 控件布局完成后重新计算,确保 "默认"、"操作" 列自适应内容宽度
_connectionTable->resizeColumnsToContents();
// 为按钮列预留最小宽度,避免被压缩或计算为 0
if (_connectionTable->columnCount() > 3)
_connectionTable->setColumnWidth(3, qMax(_connectionTable->columnWidth(3), 70));
if (_connectionTable->columnCount() > 4)
_connectionTable->setColumnWidth(4, qMax(_connectionTable->columnWidth(4), 160));
}
void DatabaseConnectionConfigDialog::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
// 首次显示后控件几何已完成,重新自适应列宽
resizeTableColumns();
} }
void DatabaseConnectionConfigDialog::addConnection() void DatabaseConnectionConfigDialog::addConnection()
{ {
ElaDatabaseConnectionDialog dialog(this); ElaDatabaseConnectionDialog dialog(this);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QSettings settings("Omnitool", "DatabaseConnections"); QSettings settings(QDir(appConfigDir()).filePath("config.ini"), QSettings::IniFormat);
QString key = "connection_" + QString::number(QDateTime::currentMSecsSinceEpoch()); QString key = "connection_" + QString::number(QDateTime::currentMSecsSinceEpoch());
settings.beginGroup(key); settings.beginGroup(key);
@@ -245,7 +269,8 @@ void DatabaseConnectionConfigDialog::addConnection()
settings.setValue("dbType", dialog.getDatabaseType()); settings.setValue("dbType", dialog.getDatabaseType());
settings.setValue("host", dialog.getHostName()); settings.setValue("host", dialog.getHostName());
settings.setValue("port", dialog.getPort()); settings.setValue("port", dialog.getPort());
settings.setValue("database", dialog.getDatabaseName()); // SQLite 类型为文件路径
settings.setValue("database", dialog.getDatabaseType() == "SQLite" ? dialog.getDatabaseFileName() : dialog.getDatabaseName());
settings.setValue("username", dialog.getUserName()); settings.setValue("username", dialog.getUserName());
settings.setValue("password", dialog.getPassword()); settings.setValue("password", dialog.getPassword());
settings.endGroup(); settings.endGroup();
@@ -266,7 +291,7 @@ void DatabaseConnectionConfigDialog::editConnection(int row)
return; return;
} }
QSettings settings("Omnitool", "DatabaseConnections"); QSettings settings(QDir(appConfigDir()).filePath("config.ini"), QSettings::IniFormat);
settings.beginGroup(key); settings.beginGroup(key);
QString dbType = settings.value("dbType", "MySQL").toString(); QString dbType = settings.value("dbType", "MySQL").toString();
QString connectionName = settings.value("name", key).toString(); QString connectionName = settings.value("name", key).toString();
@@ -282,7 +307,11 @@ void DatabaseConnectionConfigDialog::editConnection(int row)
dialog.setConnectionName(connectionName); dialog.setConnectionName(connectionName);
dialog.setHostName(host); dialog.setHostName(host);
dialog.setPort(port); dialog.setPort(port);
if (dbType == "SQLite") {
dialog.setDatabaseFileName(database);
} else {
dialog.setDatabaseName(database); dialog.setDatabaseName(database);
}
dialog.setUserName(username); dialog.setUserName(username);
dialog.setPassword(password); dialog.setPassword(password);
@@ -292,7 +321,7 @@ void DatabaseConnectionConfigDialog::editConnection(int row)
settings.setValue("dbType", dialog.getDatabaseType()); settings.setValue("dbType", dialog.getDatabaseType());
settings.setValue("host", dialog.getHostName()); settings.setValue("host", dialog.getHostName());
settings.setValue("port", dialog.getPort()); settings.setValue("port", dialog.getPort());
settings.setValue("database", dialog.getDatabaseName()); settings.setValue("database", dialog.getDatabaseType() == "SQLite" ? dialog.getDatabaseFileName() : dialog.getDatabaseName());
settings.setValue("username", dialog.getUserName()); settings.setValue("username", dialog.getUserName());
settings.setValue("password", dialog.getPassword()); settings.setValue("password", dialog.getPassword());
settings.endGroup(); settings.endGroup();
@@ -312,7 +341,7 @@ void DatabaseConnectionConfigDialog::deleteConnection(int row)
if (QMessageBox::question(this, "确认删除", "确定要删除此连接吗?", if (QMessageBox::question(this, "确认删除", "确定要删除此连接吗?",
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
if (!key.isEmpty()) { if (!key.isEmpty()) {
QSettings settings("Omnitool", "DatabaseConnections"); QSettings settings(QDir(appConfigDir()).filePath("config.ini"), QSettings::IniFormat);
settings.remove(key); settings.remove(key);
} }
@@ -348,7 +377,7 @@ void DatabaseConnectionConfigDialog::setDefault(int row)
return; return;
} }
QSettings settings("Omnitool", "DatabaseConnections"); QSettings settings(QDir(appConfigDir()).filePath("config.ini"), QSettings::IniFormat);
QStringList groups = settings.childGroups(); QStringList groups = settings.childGroups();
for (const QString& group : groups) { for (const QString& group : groups) {
@@ -3,6 +3,7 @@
#include <QDialog> #include <QDialog>
#include <QTableWidget> #include <QTableWidget>
#include <QShowEvent>
class ElaLineEdit; class ElaLineEdit;
class ElaPushButton; class ElaPushButton;
@@ -18,6 +19,9 @@ public:
QString getSelectedConnectionKey() const { return _selectedConnectionKey; } QString getSelectedConnectionKey() const { return _selectedConnectionKey; }
protected:
void showEvent(QShowEvent* event) override;
private: private:
QString _selectedConnectionKey; QString _selectedConnectionKey;
void initUI(); void initUI();
@@ -30,6 +34,7 @@ private:
void setDefault(int row); void setDefault(int row);
void exportConfig(); void exportConfig();
void importConfig(); void importConfig();
void resizeTableColumns();
private: private:
ElaLineEdit* _searchEdit; ElaLineEdit* _searchEdit;
+162 -159
View File
@@ -2,11 +2,8 @@
#include "ElaLineEdit.h" #include "ElaLineEdit.h"
#include "ElaComboBox.h" #include "ElaComboBox.h"
#include "ElaPushButton.h" #include "ElaPushButton.h"
#include "ElaToolButton.h"
#include "ElaText.h" #include "ElaText.h"
#include "ElaMessageBar.h" #include "ElaMessageBar.h"
#include "ElaIcon.h"
#include "connectors/DatabaseConnector.h"
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QGridLayout> #include <QGridLayout>
@@ -14,31 +11,37 @@
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QSqlError> #include <QSqlError>
#include <QFileDialog> #include <QFileDialog>
#include <QDir>
ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent) ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
: QDialog(parent) : QDialog(parent)
{ {
setWindowTitle("数据库连接"); setWindowTitle("数据库连接");
setMinimumWidth(500); // 固定宽度,高度随显示的控件数量自适应
setFixedWidth(500);
setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint); setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint);
QVBoxLayout* mainLayout = new QVBoxLayout(this); QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(30, 30, 30, 30); mainLayout->setContentsMargins(30, 24, 30, 24);
mainLayout->setSpacing(24); mainLayout->setSpacing(10);
ElaText* titleText = new ElaText("数据库连接配置"); ElaText* titleText = new ElaText("数据库连接配置");
titleText->setTextStyle(ElaTextType::Body); titleText->setTextStyle(ElaTextType::Body);
titleText->setStyleSheet("font-size: 20px;"); titleText->setStyleSheet("font-size: 20px;");
titleText->setContentsMargins(0, 0, 0, 4);
titleText->setFixedHeight(28);
mainLayout->addWidget(titleText, 0, Qt::AlignCenter); mainLayout->addWidget(titleText, 0, Qt::AlignCenter);
_formLayout = new QGridLayout(); _formLayout = new QGridLayout();
_formLayout->setVerticalSpacing(12); _formLayout->setVerticalSpacing(14);
_formLayout->setHorizontalSpacing(15); _formLayout->setHorizontalSpacing(12);
_formLayout->setColumnStretch(0, 1); // 标签列固定最小宽度(容纳"数据库文件""节点名称"),输入列伸展
_formLayout->setColumnStretch(3, 1); _formLayout->setColumnStretch(1, 0);
_formLayout->setColumnStretch(2, 1);
_formLayout->setColumnMinimumWidth(1, 92);
// 先将布局挂到主布局(让 layout 有 parent),否则 addWidget 时 widget 不会跟随 dialog
mainLayout->addLayout(_formLayout);
// Row 0: 连接名称(所有类型都显示) // ---- Row 0: 连接名称(所有类型都显示) ----
_connectionNameLabel = new ElaText("连接名称"); _connectionNameLabel = new ElaText("连接名称");
_connectionNameLabel->setStyleSheet("font-size: 13px;"); _connectionNameLabel->setStyleSheet("font-size: 13px;");
_connectionNameLineEdit = new ElaLineEdit(); _connectionNameLineEdit = new ElaLineEdit();
@@ -46,15 +49,15 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_connectionNameLabel, 0, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_connectionNameLabel, 0, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_connectionNameLineEdit, 0, 2); _formLayout->addWidget(_connectionNameLineEdit, 0, 2);
// Row 1: 数据库类型 // ---- Row 1: 数据库类型(所有类型都显示) ----
ElaText* dbTypeLabel = new ElaText("数据库类型"); _dbTypeLabel = new ElaText("数据库类型");
dbTypeLabel->setStyleSheet("font-size: 13px;"); _dbTypeLabel->setStyleSheet("font-size: 13px;");
_dbTypeComboBox = new ElaComboBox(); _dbTypeComboBox = new ElaComboBox();
_dbTypeComboBox->addItems({"MySQL", "SQLite", "Oracle", "MDB-SQL"}); _dbTypeComboBox->addItems({"MySQL", "SQLite", "Oracle", "MDB-SQL"});
_formLayout->addWidget(dbTypeLabel, 1, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_dbTypeLabel, 1, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_dbTypeComboBox, 1, 2); _formLayout->addWidget(_dbTypeComboBox, 1, 2);
// Row 2: 主机地址 // ---- Row 2: 主机地址(MySQL/Oracle) ----
_hostLabel = new ElaText("<font color='red'>*</font>主机地址"); _hostLabel = new ElaText("<font color='red'>*</font>主机地址");
_hostLabel->setStyleSheet("font-size: 13px;"); _hostLabel->setStyleSheet("font-size: 13px;");
_hostLineEdit = new ElaLineEdit(); _hostLineEdit = new ElaLineEdit();
@@ -62,7 +65,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_hostLabel, 2, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_hostLabel, 2, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_hostLineEdit, 2, 2); _formLayout->addWidget(_hostLineEdit, 2, 2);
// Row 3: 端口 // ---- Row 3: 端口(MySQL/Oracle) ----
_portLabel = new ElaText("<font color='red'>*</font>端口"); _portLabel = new ElaText("<font color='red'>*</font>端口");
_portLabel->setStyleSheet("font-size: 13px;"); _portLabel->setStyleSheet("font-size: 13px;");
_portLineEdit = new ElaLineEdit(); _portLineEdit = new ElaLineEdit();
@@ -70,7 +73,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_portLabel, 3, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_portLabel, 3, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_portLineEdit, 3, 2); _formLayout->addWidget(_portLineEdit, 3, 2);
// Row 4: 数据库名称 // ---- Row 4: 数据库名称(仅 MySQL) ----
_databaseNameLabel = new ElaText("数据库名称"); _databaseNameLabel = new ElaText("数据库名称");
_databaseNameLabel->setStyleSheet("font-size: 13px;"); _databaseNameLabel->setStyleSheet("font-size: 13px;");
_databaseNameLineEdit = new ElaLineEdit(); _databaseNameLineEdit = new ElaLineEdit();
@@ -78,7 +81,26 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_databaseNameLabel, 4, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_databaseNameLabel, 4, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_databaseNameLineEdit, 4, 2); _formLayout->addWidget(_databaseNameLineEdit, 4, 2);
// Row 5: 用户名 // ---- Row 4b: SQLite 数据库文件 + 浏览(仅 SQLite)----
// 用 column 0,1,2,3 而非 row 4 列 1,2,3,避免与 _databaseNameLabel 同行冲突
// 这里用一个独立行(row 4 但 col 1,2 已被占用 → 改用 row 4 整个行被 MySQL 占用)
// 改用 addWidget 时 row=4 同一行,但仅 SQLite 时隐藏 _databaseNameLabel
_dbFileLabel = new ElaText("数据库文件");
_dbFileLabel->setStyleSheet("font-size: 13px;");
_dbFileLineEdit = new ElaLineEdit();
_dbFileLineEdit->setPlaceholderText("请选择 .db / .sqlite 文件");
_browseButton = new ElaPushButton("浏览...");
_browseButton->setFixedWidth(80);
// SQLite 行使用 row 4,但与"数据库名称"(MySQL)使用同一行
// 切换时只显示对应类型那一行的 widget
// 注意:row 4 已被 _databaseNameLabel/_databaseNameLineEdit 占用
// SQLite 的 label/file 放到 row 4 column 1,2;browse 放到 row 4 column 3
// 切换时通过 hide()/show() 切换可见性
_formLayout->addWidget(_dbFileLabel, 4, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_dbFileLineEdit, 4, 2);
_formLayout->addWidget(_browseButton, 4, 3, Qt::AlignVCenter);
// ---- Row 5: 用户名(MySQL/Oracle) ----
_userNameLabel = new ElaText("<font color='red'>*</font>用户名"); _userNameLabel = new ElaText("<font color='red'>*</font>用户名");
_userNameLabel->setStyleSheet("font-size: 13px;"); _userNameLabel->setStyleSheet("font-size: 13px;");
_userNameLineEdit = new ElaLineEdit(); _userNameLineEdit = new ElaLineEdit();
@@ -86,7 +108,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_userNameLabel, 5, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_userNameLabel, 5, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_userNameLineEdit, 5, 2); _formLayout->addWidget(_userNameLineEdit, 5, 2);
// Row 6: 密码 // ---- Row 6: 密码(MySQL/Oracle) ----
_passwordLabel = new ElaText("<font color='red'>*</font>密码"); _passwordLabel = new ElaText("<font color='red'>*</font>密码");
_passwordLabel->setStyleSheet("font-size: 13px;"); _passwordLabel->setStyleSheet("font-size: 13px;");
_passwordLineEdit = new ElaLineEdit(); _passwordLineEdit = new ElaLineEdit();
@@ -95,7 +117,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_passwordLabel, 6, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_passwordLabel, 6, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_passwordLineEdit, 6, 2); _formLayout->addWidget(_passwordLineEdit, 6, 2);
// Row 7: 服务名 // ---- Row 7: 服务名(仅 Oracle) ----
_serviceNameLabel = new ElaText("<font color='red'>*</font>服务名"); _serviceNameLabel = new ElaText("<font color='red'>*</font>服务名");
_serviceNameLabel->setStyleSheet("font-size: 13px;"); _serviceNameLabel->setStyleSheet("font-size: 13px;");
_serviceNameLineEdit = new ElaLineEdit(); _serviceNameLineEdit = new ElaLineEdit();
@@ -103,7 +125,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_serviceNameLabel, 7, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_serviceNameLabel, 7, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_serviceNameLineEdit, 7, 2); _formLayout->addWidget(_serviceNameLineEdit, 7, 2);
// Row 8: 节点名称 // ---- Row 8: 节点名称(仅 MDB-SQL) ----
_nodeNameLabel = new ElaText("<font color='red'>*</font>节点名称"); _nodeNameLabel = new ElaText("<font color='red'>*</font>节点名称");
_nodeNameLabel->setStyleSheet("font-size: 13px;"); _nodeNameLabel->setStyleSheet("font-size: 13px;");
_nodeNameLineEdit = new ElaLineEdit(); _nodeNameLineEdit = new ElaLineEdit();
@@ -111,7 +133,7 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_nodeNameLabel, 8, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_nodeNameLabel, 8, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_nodeNameLineEdit, 8, 2); _formLayout->addWidget(_nodeNameLineEdit, 8, 2);
// Row 9: 许可证编号 // ---- Row 9: 许可证编号(仅 MDB-SQL) ----
_licenseKeyLabel = new ElaText("许可证编号"); _licenseKeyLabel = new ElaText("许可证编号");
_licenseKeyLabel->setStyleSheet("font-size: 13px;"); _licenseKeyLabel->setStyleSheet("font-size: 13px;");
_licenseKeyLineEdit = new ElaLineEdit(); _licenseKeyLineEdit = new ElaLineEdit();
@@ -119,19 +141,6 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
_formLayout->addWidget(_licenseKeyLabel, 9, 1, Qt::AlignRight | Qt::AlignVCenter); _formLayout->addWidget(_licenseKeyLabel, 9, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_licenseKeyLineEdit, 9, 2); _formLayout->addWidget(_licenseKeyLineEdit, 9, 2);
// Row 10: SQLite数据库文件路径
_sqliteFileLabel = new ElaText("<font color='red'>*</font>数据库文件");
_sqliteFileLabel->setStyleSheet("font-size: 13px;");
_sqliteFileLineEdit = new ElaLineEdit();
_sqliteFileLineEdit->setPlaceholderText("请选择或输入 SQLite 数据库文件路径");
_sqliteBrowseButton = new ElaToolButton(this);
_sqliteBrowseButton->setText("浏览...");
_formLayout->addWidget(_sqliteFileLabel, 10, 1, Qt::AlignRight | Qt::AlignVCenter);
_formLayout->addWidget(_sqliteFileLineEdit, 10, 2);
_formLayout->addWidget(_sqliteBrowseButton, 10, 3);
mainLayout->addLayout(_formLayout);
QHBoxLayout* buttonLayout = new QHBoxLayout(); QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(12); buttonLayout->setSpacing(12);
@@ -147,10 +156,10 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
mainLayout->addLayout(buttonLayout); mainLayout->addLayout(buttonLayout);
connect(_dbTypeComboBox, &ElaComboBox::currentTextChanged, this, &ElaDatabaseConnectionDialog::onDbTypeChanged); connect(_dbTypeComboBox, &ElaComboBox::currentTextChanged, this, &ElaDatabaseConnectionDialog::onDbTypeChanged);
connect(_browseButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::onBrowseClicked);
connect(_testButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::onTestConnectionClicked); connect(_testButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::onTestConnectionClicked);
connect(_okButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::onOkClicked); connect(_okButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::onOkClicked);
connect(_cancelButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::reject); connect(_cancelButton, &ElaPushButton::clicked, this, &ElaDatabaseConnectionDialog::reject);
connect(_sqliteBrowseButton, &ElaToolButton::clicked, this, &ElaDatabaseConnectionDialog::onBrowseSqliteFile);
connect(_hostLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onHostTextChanged); connect(_hostLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onHostTextChanged);
connect(_portLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onPortTextChanged); connect(_portLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onPortTextChanged);
@@ -158,8 +167,8 @@ ElaDatabaseConnectionDialog::ElaDatabaseConnectionDialog(QWidget* parent)
connect(_serviceNameLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onServiceNameTextChanged); connect(_serviceNameLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onServiceNameTextChanged);
connect(_nodeNameLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onNodeNameTextChanged); connect(_nodeNameLineEdit, &ElaLineEdit::textChanged, this, &ElaDatabaseConnectionDialog::onNodeNameTextChanged);
// 初始化可见性(不再清空 layout)
updateFormFields(); updateFormFields();
adjustSize();
} }
ElaDatabaseConnectionDialog::~ElaDatabaseConnectionDialog() ElaDatabaseConnectionDialog::~ElaDatabaseConnectionDialog()
@@ -168,72 +177,62 @@ ElaDatabaseConnectionDialog::~ElaDatabaseConnectionDialog()
void ElaDatabaseConnectionDialog::updateFormFields() void ElaDatabaseConnectionDialog::updateFormFields()
{ {
// 不动 layout:通过 hide/show 切换可见性,避免 widget 漂移或丢失
// 所有 widget 已在构造函数中添加到 _formLayout 的固定 row/col,
// 此处仅按 dbType 控制每行 widget 的可见性。
QString dbType = _dbTypeComboBox->currentText(); QString dbType = _dbTypeComboBox->currentText();
// 连接名称始终显示 // 共用:连接名称、数据库类型
_connectionNameLabel->show(); _connectionNameLabel->setVisible(true);
_connectionNameLineEdit->show(); _connectionNameLineEdit->setVisible(true);
_dbTypeLabel->setVisible(true);
_dbTypeComboBox->setVisible(true);
// 默认隐藏可选字段 // 默认全部隐藏
_hostLabel->hide(); auto hideAll = [&]() {
_hostLineEdit->hide(); _hostLabel->hide(); _hostLineEdit->hide();
_portLabel->hide(); _portLabel->hide(); _portLineEdit->hide();
_portLineEdit->hide(); _databaseNameLabel->hide(); _databaseNameLineEdit->hide();
_databaseNameLabel->hide(); _dbFileLabel->hide(); _dbFileLineEdit->hide(); _browseButton->hide();
_databaseNameLineEdit->hide(); _userNameLabel->hide(); _userNameLineEdit->hide();
_userNameLabel->hide(); _passwordLabel->hide(); _passwordLineEdit->hide();
_userNameLineEdit->hide(); _serviceNameLabel->hide(); _serviceNameLineEdit->hide();
_passwordLabel->hide(); _nodeNameLabel->hide(); _nodeNameLineEdit->hide();
_passwordLineEdit->hide(); _licenseKeyLabel->hide(); _licenseKeyLineEdit->hide();
_serviceNameLabel->hide(); };
_serviceNameLineEdit->hide();
_nodeNameLabel->hide();
_nodeNameLineEdit->hide();
_licenseKeyLabel->hide();
_licenseKeyLineEdit->hide();
_sqliteFileLabel->hide();
_sqliteFileLineEdit->hide();
_sqliteBrowseButton->hide();
if (dbType == "MDB-SQL") { if (dbType == "SQLite") {
_nodeNameLabel->show(); hideAll();
_nodeNameLineEdit->show(); _dbFileLabel->show(); _dbFileLineEdit->show(); _browseButton->show();
_licenseKeyLabel->show();
_licenseKeyLineEdit->show();
} else if (dbType == "Oracle") {
_hostLabel->show();
_hostLineEdit->show();
_portLabel->show();
_portLineEdit->show();
_userNameLabel->show();
_userNameLineEdit->show();
_passwordLabel->show();
_passwordLineEdit->show();
_serviceNameLabel->show();
_serviceNameLineEdit->show();
} else if (dbType == "MySQL") { } else if (dbType == "MySQL") {
_hostLabel->show(); hideAll();
_hostLineEdit->show(); _hostLabel->show(); _hostLineEdit->show();
_portLabel->show(); _portLabel->show(); _portLineEdit->show();
_portLineEdit->show(); _databaseNameLabel->show(); _databaseNameLineEdit->show();
_databaseNameLabel->show(); _userNameLabel->show(); _userNameLineEdit->show();
_databaseNameLineEdit->show(); _passwordLabel->show(); _passwordLineEdit->show();
_userNameLabel->show(); } else if (dbType == "Oracle") {
_userNameLineEdit->show(); hideAll();
_passwordLabel->show(); _hostLabel->show(); _hostLineEdit->show();
_passwordLineEdit->show(); _portLabel->show(); _portLineEdit->show();
} else if (dbType == "SQLite") { _userNameLabel->show(); _userNameLineEdit->show();
// SQLite 需要数据库文件路径 _passwordLabel->show(); _passwordLineEdit->show();
_sqliteFileLabel->show(); _serviceNameLabel->show(); _serviceNameLineEdit->show();
_sqliteFileLineEdit->show(); } else if (dbType == "MDB-SQL") {
_sqliteBrowseButton->show(); hideAll();
_nodeNameLabel->show(); _nodeNameLineEdit->show();
_licenseKeyLabel->show(); _licenseKeyLineEdit->show();
} else {
hideAll();
} }
// 窗口高度随显示的控件数量自适应(标题位置因固定在 VBoxLayout 顶部而不变)
adjustSize();
} }
void ElaDatabaseConnectionDialog::onDbTypeChanged(const QString& /*type*/) void ElaDatabaseConnectionDialog::onDbTypeChanged(const QString& /*type*/)
{ {
updateFormFields(); updateFormFields();
adjustSize();
} }
void ElaDatabaseConnectionDialog::onHostTextChanged(const QString& text) void ElaDatabaseConnectionDialog::onHostTextChanged(const QString& text)
@@ -316,13 +315,6 @@ QString ElaDatabaseConnectionDialog::getConnectionName() const
QString ElaDatabaseConnectionDialog::getDatabaseName() const QString ElaDatabaseConnectionDialog::getDatabaseName() const
{ {
if (_dbTypeComboBox->currentText() == "SQLite") {
return _sqliteFileLineEdit->text();
}
// Oracle 使用服务名作为 database 字段
if (_dbTypeComboBox->currentText() == "Oracle") {
return _serviceNameLineEdit->text();
}
return _databaseNameLineEdit->text(); return _databaseNameLineEdit->text();
} }
@@ -351,6 +343,29 @@ QString ElaDatabaseConnectionDialog::getLicenseKey() const
return _licenseKeyLineEdit->text(); return _licenseKeyLineEdit->text();
} }
QString ElaDatabaseConnectionDialog::getDatabaseFileName() const
{
return _dbFileLineEdit->text();
}
void ElaDatabaseConnectionDialog::setDatabaseFileName(const QString& fileName)
{
_dbFileLineEdit->setText(fileName);
}
void ElaDatabaseConnectionDialog::onBrowseClicked()
{
QString fileName = QFileDialog::getOpenFileName(
this,
"选择 SQLite 数据库文件",
QString(),
"SQLite 数据库 (*.db *.sqlite *.db3 *.sqlite3);;所有文件 (*.*)");
if (!fileName.isEmpty()) {
_dbFileLineEdit->setText(fileName);
clearErrorStyle(_dbFileLineEdit);
}
}
void ElaDatabaseConnectionDialog::setDatabaseType(const QString& type) void ElaDatabaseConnectionDialog::setDatabaseType(const QString& type)
{ {
int index = _dbTypeComboBox->findText(type); int index = _dbTypeComboBox->findText(type);
@@ -377,14 +392,8 @@ void ElaDatabaseConnectionDialog::setConnectionName(const QString& name)
void ElaDatabaseConnectionDialog::setDatabaseName(const QString& name) void ElaDatabaseConnectionDialog::setDatabaseName(const QString& name)
{ {
if (_dbTypeComboBox->currentText() == "SQLite") {
_sqliteFileLineEdit->setText(name);
} else if (_dbTypeComboBox->currentText() == "Oracle") {
_serviceNameLineEdit->setText(name);
} else {
_databaseNameLineEdit->setText(name); _databaseNameLineEdit->setText(name);
} }
}
void ElaDatabaseConnectionDialog::setUserName(const QString& userName) void ElaDatabaseConnectionDialog::setUserName(const QString& userName)
{ {
@@ -416,22 +425,12 @@ void ElaDatabaseConnectionDialog::onTestConnectionClicked()
QString dbType = _dbTypeComboBox->currentText(); QString dbType = _dbTypeComboBox->currentText();
QString host = _hostLineEdit->text(); QString host = _hostLineEdit->text();
QString port = _portLineEdit->text(); QString port = _portLineEdit->text();
QString database = _databaseNameLineEdit->text();
QString username = _userNameLineEdit->text(); QString username = _userNameLineEdit->text();
QString password = _passwordLineEdit->text(); QString password = _passwordLineEdit->text();
QString sqliteFile = _sqliteFileLineEdit->text();
bool hasError = false; bool hasError = false;
// 字段校验 if (dbType != "SQLite") {
if (dbType == "SQLite") {
if (sqliteFile.isEmpty()) {
setErrorStyle(_sqliteFileLineEdit);
hasError = true;
}
if (hasError) {
ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请选择 SQLite 数据库文件", 3000, this);
return;
}
} else {
if (host.isEmpty()) { if (host.isEmpty()) {
setErrorStyle(_hostLineEdit); setErrorStyle(_hostLineEdit);
hasError = true; hasError = true;
@@ -440,73 +439,90 @@ void ElaDatabaseConnectionDialog::onTestConnectionClicked()
setErrorStyle(_portLineEdit); setErrorStyle(_portLineEdit);
hasError = true; hasError = true;
} }
if ((dbType == "MySQL" || dbType == "Oracle") && password.isEmpty()) { }
if (dbType == "MySQL" && password.isEmpty()) {
setErrorStyle(_passwordLineEdit); setErrorStyle(_passwordLineEdit);
hasError = true; hasError = true;
} }
if (dbType == "Oracle") { if (dbType == "Oracle") {
if (username.isEmpty()) { if (username.isEmpty()) {
setErrorStyle(_userNameLineEdit); setErrorStyle(_userNameLineEdit);
hasError = true; hasError = true;
} }
if (password.isEmpty()) {
setErrorStyle(_passwordLineEdit);
hasError = true;
}
if (_serviceNameLineEdit->text().isEmpty()) { if (_serviceNameLineEdit->text().isEmpty()) {
setErrorStyle(_serviceNameLineEdit); setErrorStyle(_serviceNameLineEdit);
hasError = true; hasError = true;
} }
} }
if (dbType == "MDB-SQL") { if (dbType == "MDB-SQL") {
if (_nodeNameLineEdit->text().isEmpty()) { if (_nodeNameLineEdit->text().isEmpty()) {
setErrorStyle(_nodeNameLineEdit); setErrorStyle(_nodeNameLineEdit);
hasError = true; hasError = true;
} }
} }
if (hasError) { if (hasError) {
ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请填写所有必填项", 3000, this); ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请填写所有必填项", 3000, this);
return; return;
} }
QString driverName;
if (dbType == "MySQL") {
driverName = "QMYSQL";
} else if (dbType == "SQLite") {
driverName = "QSQLITE";
} else if (dbType == "Oracle") {
driverName = "QOCI";
} }
// 构造 ConnectionParams,复用 createConnector() 使测试连接与实际连接使用完全相同逻辑 QString connectionName = "test_connection";
ConnectionParams params; if (QSqlDatabase::contains(connectionName)) {
params.dbType = dbType; QSqlDatabase::removeDatabase(connectionName);
params.host = host; }
params.port = port;
params.database = getDatabaseName(); // Oracle 返回服务名,SQLite 返回文件路径
params.username = username;
params.password = password;
DatabaseConnector* connector = createConnector(params, "test_connection"); QSqlDatabase db = QSqlDatabase::addDatabase(driverName, connectionName);
if (!connector) {
ElaMessageBar::error(ElaMessageBarType::Top, "错误", "不支持的数据库类型: " + dbType, 3000, this); if (dbType == "SQLite") {
if (_dbFileLineEdit->text().isEmpty()) {
ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请选择 SQLite 数据库文件", 3000, this);
return; return;
} }
db.setDatabaseName(_dbFileLineEdit->text());
if (connector->open()) {
ElaMessageBar::success(ElaMessageBarType::Top, "成功", "连接测试成功", 3000, this);
connector->close();
} else { } else {
ElaMessageBar::error(ElaMessageBarType::Top, "错误", "无法连接数据库: " + connector->database().lastError().text(), 5000, this); db.setHostName(host);
db.setPort(port.toInt());
db.setDatabaseName(database);
db.setUserName(username);
db.setPassword(password);
} }
delete connector; if (db.open()) {
ElaMessageBar::success(ElaMessageBarType::Top, "成功", "连接测试成功", 3000, this);
db.close();
} else {
ElaMessageBar::error(ElaMessageBarType::Top, "错误", "无法连接数据库: " + db.lastError().text(), 5000, this);
}
QSqlDatabase::removeDatabase(connectionName);
} }
void ElaDatabaseConnectionDialog::onOkClicked() void ElaDatabaseConnectionDialog::onOkClicked()
{ {
QString dbType = _dbTypeComboBox->currentText(); QString dbType = _dbTypeComboBox->currentText();
QString sqliteFile = _sqliteFileLineEdit->text();
bool hasError = false; bool hasError = false;
// SQLite 特殊处理
if (dbType == "SQLite") { if (dbType == "SQLite") {
if (sqliteFile.isEmpty()) { if (_dbFileLineEdit->text().isEmpty()) {
setErrorStyle(_sqliteFileLineEdit); setErrorStyle(_dbFileLineEdit);
hasError = true; hasError = true;
} }
if (hasError) {
ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请选择 SQLite 数据库文件", 3000, this);
return;
}
} else { } else {
if (_hostLineEdit->text().isEmpty()) { if (_hostLineEdit->text().isEmpty()) {
setErrorStyle(_hostLineEdit); setErrorStyle(_hostLineEdit);
@@ -517,6 +533,7 @@ void ElaDatabaseConnectionDialog::onOkClicked()
setErrorStyle(_portLineEdit); setErrorStyle(_portLineEdit);
hasError = true; hasError = true;
} }
}
if (dbType == "MySQL" && _passwordLineEdit->text().isEmpty()) { if (dbType == "MySQL" && _passwordLineEdit->text().isEmpty()) {
setErrorStyle(_passwordLineEdit); setErrorStyle(_passwordLineEdit);
@@ -549,20 +566,6 @@ void ElaDatabaseConnectionDialog::onOkClicked()
ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请填写所有必填项", 3000, this); ElaMessageBar::warning(ElaMessageBarType::Top, "警告", "请填写所有必填项", 3000, this);
return; return;
} }
}
accept(); accept();
} }
void ElaDatabaseConnectionDialog::onBrowseSqliteFile()
{
QString filePath = QFileDialog::getOpenFileName(
this,
"选择 SQLite 数据库文件",
QDir::homePath(),
"SQLite 数据库文件 (*.db *.sqlite *.sqlite3 *.db3);;所有文件 (*)"
);
if (!filePath.isEmpty()) {
_sqliteFileLineEdit->setText(filePath);
}
}
+10 -6
View File
@@ -2,13 +2,14 @@
#define ELADATABASECONNECTIONDIALOG_H #define ELADATABASECONNECTIONDIALOG_H
#include <QDialog> #include <QDialog>
#include <QLabel>
#include <QGridLayout> #include <QGridLayout>
#include "ElaLineEdit.h" #include "ElaLineEdit.h"
#include "ElaComboBox.h" #include "ElaComboBox.h"
#include "ElaPushButton.h" #include "ElaPushButton.h"
#include "ElaText.h" #include "ElaText.h"
class ElaToolButton; class QGridLayout;
class ElaDatabaseConnectionDialog : public QDialog class ElaDatabaseConnectionDialog : public QDialog
{ {
@@ -22,6 +23,8 @@ public:
QString getPort() const; QString getPort() const;
QString getConnectionName() const; QString getConnectionName() const;
QString getDatabaseName() const; QString getDatabaseName() const;
QString getDatabaseFileName() const;
void setDatabaseFileName(const QString& fileName);
QString getUserName() const; QString getUserName() const;
QString getPassword() const; QString getPassword() const;
QString getServiceName() const; QString getServiceName() const;
@@ -48,7 +51,7 @@ private Q_SLOTS:
void onPasswordTextChanged(const QString& text); void onPasswordTextChanged(const QString& text);
void onServiceNameTextChanged(const QString& text); void onServiceNameTextChanged(const QString& text);
void onNodeNameTextChanged(const QString& text); void onNodeNameTextChanged(const QString& text);
void onBrowseSqliteFile(); void onBrowseClicked();
private: private:
void updateFormFields(); void updateFormFields();
@@ -57,6 +60,11 @@ private:
QGridLayout* _formLayout; QGridLayout* _formLayout;
ElaComboBox* _dbTypeComboBox; ElaComboBox* _dbTypeComboBox;
ElaText* _dbTypeLabel;
ElaText* _dbFileLabel;
ElaLineEdit* _dbFileLineEdit;
ElaPushButton* _browseButton;
ElaText* _hostLabel; ElaText* _hostLabel;
ElaLineEdit* _hostLineEdit; ElaLineEdit* _hostLineEdit;
@@ -85,10 +93,6 @@ private:
ElaText* _licenseKeyLabel; ElaText* _licenseKeyLabel;
ElaLineEdit* _licenseKeyLineEdit; ElaLineEdit* _licenseKeyLineEdit;
ElaText* _sqliteFileLabel;
ElaLineEdit* _sqliteFileLineEdit;
ElaToolButton* _sqliteBrowseButton;
ElaPushButton* _testButton; ElaPushButton* _testButton;
ElaPushButton* _okButton; ElaPushButton* _okButton;
ElaPushButton* _cancelButton; ElaPushButton* _cancelButton;
+2
View File
@@ -24,6 +24,8 @@ void MainWindow::initWindow()
resize(900, 600); resize(900, 600);
setMinimumSize(800, 500); setMinimumSize(800, 500);
setUserInfoCardVisible(false); setUserInfoCardVisible(false);
// 默认以最大化窗口启动
showMaximized();
// 隐藏返回和前进按钮 // 隐藏返回和前进按钮
+49
View File
@@ -33,7 +33,9 @@
#include <QTextEdit> #include <QTextEdit>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSet> #include <QSet>
#include <QSettings>
#include "utils/logmanager.h" #include "utils/logmanager.h"
#include "utils/configmanager.h"
#include <Qsci/qsciscintilla.h> #include <Qsci/qsciscintilla.h>
#include <Qsci/qscilexersql.h> #include <Qsci/qscilexersql.h>
#include <Qsci/qsciapis.h> #include <Qsci/qsciapis.h>
@@ -325,14 +327,50 @@ void DatabaseManagerPage::onConnectionManage()
QString selectedKey = dialog.getSelectedConnectionKey(); QString selectedKey = dialog.getSelectedConnectionKey();
if (!selectedKey.isEmpty()) { if (!selectedKey.isEmpty()) {
_currentConnectionKey = selectedKey; _currentConnectionKey = selectedKey;
// 记住本次手动加载的连接,作为下一次启动的默认连接
markDefaultConnection(selectedKey);
updateConnectionInfo(); updateConnectionInfo();
refreshTables(); refreshTables();
} }
} }
} }
void DatabaseManagerPage::markDefaultConnection(const QString& key)
{
if (key.isEmpty()) return;
QSettings* settings = appConnectionsSettings();
const QStringList groups = settings->childGroups();
for (const QString& group : groups) {
settings->beginGroup(group);
settings->setValue("isDefault", (group == key));
settings->endGroup();
}
settings->sync();
}
QString DatabaseManagerPage::getDefaultConnectionKey()
{
QSettings* settings = appConnectionsSettings();
const QStringList groups = settings->childGroups();
for (const QString& group : groups) {
settings->beginGroup(group);
bool isDefault = settings->value("isDefault", false).toBool();
settings->endGroup();
if (isDefault)
return group;
}
return QString();
}
void DatabaseManagerPage::loadConnections() void DatabaseManagerPage::loadConnections()
{ {
// 启动时自动连接上一次加载(设为默认)的数据库
QString defaultKey = getDefaultConnectionKey();
if (!defaultKey.isEmpty() && ConnectionParams::fromSettings(defaultKey).dbType != "") {
_currentConnectionKey = defaultKey;
updateConnectionInfo();
refreshTables();
}
} }
void DatabaseManagerPage::refreshTables() void DatabaseManagerPage::refreshTables()
@@ -344,6 +382,13 @@ void DatabaseManagerPage::refreshTables()
// 切换连接时关闭旧连接,确保重新建立新数据库连接 // 切换连接时关闭旧连接,确保重新建立新数据库连接
if (_connector) { if (_connector) {
// 关键:先解绑视图并销毁旧的 EditableSqlModel,
// 否则 _dataModel 内部持有的 QSqlQuery 仍指向即将被删除的数据库连接,导致后续访问崩溃
if (_dataTableView) _dataTableView->setModel(nullptr);
if (_dataModel) {
delete _dataModel;
_dataModel = nullptr;
}
delete _connector; delete _connector;
_connector = nullptr; _connector = nullptr;
} }
@@ -351,6 +396,10 @@ void DatabaseManagerPage::refreshTables()
_currentTableName.clear(); _currentTableName.clear();
_lastExecutedSql.clear(); _lastExecutedSql.clear();
_currentPage = 1; _currentPage = 1;
if (!_dataModel) {
_dataModel = new EditableSqlModel(this);
if (_dataTableView) _dataTableView->setModel(_dataModel);
}
_dataModel->clear(); _dataModel->clear();
_dataModel->clearChanges(); _dataModel->clearChanges();
+27 -15
View File
@@ -2,16 +2,22 @@
#define DATABASEMANAGERPAGE_H #define DATABASEMANAGERPAGE_H
#include <QWidget> #include <QWidget>
#include <QTableView>
#include <QLineEdit>
#include <QSqlQueryModel>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QSplitter>
#include <QListView>
#include <QLabel> #include <QLabel>
#include <QComboBox> #include <QGroupBox>
#include <QCoreApplication>
class QsciScintilla; class QsciScintilla;
class QsciLexerSQL; class QsciLexerSQL;
class QsciAPIs; class QsciAPIs;
class QComboBox;
class EditableSqlModel;
class ElaTableView; class ElaTableView;
class ElaLineEdit; class ElaLineEdit;
class ElaPushButton; class ElaPushButton;
@@ -19,8 +25,9 @@ class ElaToolButton;
class ElaComboBox; class ElaComboBox;
class ElaListView; class ElaListView;
class ElaTabWidget; class ElaTabWidget;
class EditableSqlModel;
class DatabaseConnector; class DatabaseConnector;
struct ConnectionParams;
class DatabaseManagerPage : public QWidget class DatabaseManagerPage : public QWidget
{ {
@@ -39,24 +46,27 @@ private:
bool openDatabase(); bool openDatabase();
void updateConnectionInfo(); void updateConnectionInfo();
void onConnectionManage(); void onConnectionManage();
static void markDefaultConnection(const QString& key);
static QString getDefaultConnectionKey();
void onTableDoubleClicked(const QModelIndex& index); void onTableDoubleClicked(const QModelIndex& index);
void onExecuteSql(); void onExecuteSql();
void onTableSearchTextChanged(const QString& text); void onTableSearchTextChanged(const QString& text);
void onSubmitChanges(); void onSubmitChanges();
void onExportData(); void onExportData();
void onPrevPage(); void onPreviewChanges();
void onNextPage(); void updateUndoRedoButtons();
void onPageSizeChanged(int index);
QWidget* createSqlEditorTab(); QWidget* createSqlEditorTab();
QsciScintilla* currentEditor() const; QsciScintilla* currentEditor() const;
void onAddTab(); void onAddTab();
void loadTableData(int page = 1);
void loadTableData(int page);
void onPrevPage();
void onNextPage();
void onPageSizeChanged(int index);
QString getCurrentSqlContent(); QString getCurrentSqlContent();
int _tabCounter = 0; int _tabCounter = 0;
int _currentPage = 1;
int _pageSize = 100;
private: private:
ElaListView* _tableView; ElaListView* _tableView;
@@ -68,23 +78,25 @@ private:
ElaToolButton* _addRecordButton; ElaToolButton* _addRecordButton;
ElaToolButton* _submitButton; ElaToolButton* _submitButton;
ElaToolButton* _exportButton; ElaToolButton* _exportButton;
QLabel* _connectionInfoLabel;
QLabel* _rowCountLabel;
QLabel* _pendingChangesLabel;
QLabel* _pageLabel;
ElaToolButton* _prevButton; ElaToolButton* _prevButton;
ElaToolButton* _nextButton; ElaToolButton* _nextButton;
QLabel* _connectionInfoLabel;
QLabel* _rowCountLabel;
QLabel* _pageLabel;
QLabel* _pendingChangesLabel;
QComboBox* _pageSizeCombo; QComboBox* _pageSizeCombo;
ElaTabWidget* _sqlTabWidget; ElaTabWidget* _sqlTabWidget;
EditableSqlModel* _dataModel; EditableSqlModel* _dataModel;
QStandardItemModel* _tableModel; QStandardItemModel* _tableModel;
QSortFilterProxyModel* _tableProxyModel; QSortFilterProxyModel* _tableProxyModel;
DatabaseConnector* _connector = nullptr;
QString _currentConnectionKey; QString _currentConnectionKey;
QString _currentTableName; QString _currentTableName;
QString _lastExecutedSql; QString _lastExecutedSql;
QString _lastConnectedKey;
DatabaseConnector* _connector = nullptr; // 当前数据库连接器 int _currentPage = 1;
int _pageSize = 100;
QList<QsciScintilla*> _editorList; QList<QsciScintilla*> _editorList;
QList<QsciAPIs*> _apisList; QList<QsciAPIs*> _apisList;
+19 -2
View File
@@ -24,9 +24,9 @@ ConfigManager* ConfigManager::instance()
return _instance; return _instance;
} }
void ConfigManager::loadConfig(const QString& basePath) void ConfigManager::loadConfig()
{ {
_configPath = QDir(basePath).filePath("config.ini"); _configPath = QDir(appConfigDir()).filePath("config.ini");
_settings = new QSettings(_configPath, QSettings::IniFormat); _settings = new QSettings(_configPath, QSettings::IniFormat);
_settings->beginGroup("Database"); _settings->beginGroup("Database");
@@ -117,3 +117,20 @@ void ConfigManager::saveConfig()
{ {
_settings->sync(); _settings->sync();
} }
QString appConfigDir()
{
QString dir = QDir(QCoreApplication::applicationDirPath()).filePath("config");
QDir().mkpath(dir);
return dir;
}
QSettings* appConnectionsSettings()
{
static QSettings* s = nullptr;
if (!s) {
QString path = QDir(appConfigDir()).filePath("config.ini");
s = new QSettings(path, QSettings::IniFormat);
}
return s;
}
+5 -1
View File
@@ -9,7 +9,7 @@ class ConfigManager
public: public:
static ConfigManager* instance(); static ConfigManager* instance();
void loadConfig(const QString& basePath); void loadConfig();
QString getDatabaseHost() const; QString getDatabaseHost() const;
QString getDatabasePort() const; QString getDatabasePort() const;
@@ -36,4 +36,8 @@ private:
QString _configPath; QString _configPath;
}; };
// 指向 "程序目录/config/config.ini" 的共享 QSettings(IniFormat),用于数据库连接列表存储
QSettings* appConnectionsSettings();
QString appConfigDir();
#endif // CONFIGMANAGER_H #endif // CONFIGMANAGER_H