完善属性录入整体逻辑

This commit is contained in:
duanshengchao 2025-04-11 17:14:17 +08:00
parent f714397241
commit d2696abadb
25 changed files with 1336 additions and 74 deletions

View File

@ -27,6 +27,7 @@ set(H_HEADER_FILES
include/dbStructureView.h include/dbStructureView.h
include/connectionDialog.h include/connectionDialog.h
include/messageDialog.h include/messageDialog.h
include/messageBox.h
include/settings.h include/settings.h
include/tableWidgetHoverDelegate.h include/tableWidgetHoverDelegate.h
include/customMenu.h include/customMenu.h
@ -37,6 +38,7 @@ set(H_HEADER_FILES
include/attributeTableModel.h include/attributeTableModel.h
include/attributeTableDelegate.h include/attributeTableDelegate.h
include/attributeView.h include/attributeView.h
include/attributeSelector.h
) )
set(CPP_SOURCE_FILES set(CPP_SOURCE_FILES
@ -51,6 +53,7 @@ set(CPP_SOURCE_FILES
source/dbStructureView.cpp source/dbStructureView.cpp
source/connectionDialog.cpp source/connectionDialog.cpp
source/messageDialog.cpp source/messageDialog.cpp
source/messageBox.cpp
source/settings.cpp source/settings.cpp
source/tableWidgetHoverDelegate.cpp source/tableWidgetHoverDelegate.cpp
source/customMenu.cpp source/customMenu.cpp
@ -60,6 +63,7 @@ set(CPP_SOURCE_FILES
source/attributeTableModel.cpp source/attributeTableModel.cpp
source/attributeTableDelegate.cpp source/attributeTableDelegate.cpp
source/attributeView.cpp source/attributeView.cpp
source/attributeSelector.cpp
) )
set(UI_FILES set(UI_FILES
@ -69,6 +73,7 @@ set(UI_FILES
ui/messageDialog.ui ui/messageDialog.ui
ui/modelInfoEditDialog.ui ui/modelInfoEditDialog.ui
ui/textEditWidget.ui ui/textEditWidget.ui
ui/attributeSelector.ui
) )
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 13.0.2, 2025-04-03T18:33:56. --> <!-- Written by QtCreator 13.0.2, 2025-04-09T22:30:14. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -727,7 +727,6 @@
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value> <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">E:/Code/CL-Softwares/Git/PowerModeler/build/Qt_MinGW_64_bit-Debug</value>
</valuemap> </valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value> <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap> </valuemap>

View File

@ -0,0 +1,36 @@
#ifndef ATTRIBUTESELECTOR_H
#define ATTRIBUTESELECTOR_H
#include "global.h"
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class AttributeSelector;
}
QT_END_NAMESPACE
class MainWindow;
class AttributeView;
class AttributeSelector : public QWidget
{
Q_OBJECT
public:
AttributeSelector(const QString& connection = "", QWidget *parent = nullptr);
~AttributeSelector();
void setMainWindow(MainWindow*);
private slots:
void onBtnClicked_refreshData();
void onSyncDataStatus(bool, const PaginationInfo&);
private:
Ui::AttributeSelector *ui;
MainWindow* m_pMainWindow;
AttributeView* m_attributeView;
QString m_connection;
};
#endif //ATTRIBUTESELECTOR_H

View File

@ -1,6 +1,7 @@
#ifndef ATTRIBUTETABLEDELEGATE_H #ifndef ATTRIBUTETABLEDELEGATE_H
#define ATTRIBUTETABLEDELEGATE_H #define ATTRIBUTETABLEDELEGATE_H
#include "messageDialog.h"
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QTableView> #include <QTableView>
@ -21,6 +22,7 @@ public:
void setPrompt(const QString&); void setPrompt(const QString&);
void setRegularExpression(const QString&); void setRegularExpression(const QString&);
void setErrorInfo(const QString&); void setErrorInfo(const QString&);
void setFocusToTextEdit();
signals: signals:
void confirm(); void confirm();
@ -58,6 +60,9 @@ public:
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
signals:
void showMessage(MessageDialogType,const QString&,const QString&);
private: private:
bool isEnumType(const QModelIndex&) const; bool isEnumType(const QModelIndex&) const;

View File

@ -24,14 +24,6 @@ class AttributeTableModel : public QAbstractTableModel
Q_OBJECT Q_OBJECT
public: public:
enum EditState
{
Clean = 0,
Modified,
New,
Deleted
};
struct DataType //数据类型 struct DataType //数据类型
{ {
int id; int id;
@ -53,6 +45,10 @@ public:
int columnCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
//ModelAttributeGroup getModelAttributeGroup() {return m_modelAttributeGroup;}
bool attributeTypeExistsInCurrentGroup(int, const QString&); //除数据库外,还有从内存存储的数据(当前页m_currentPageData)中进行查找判断,因为可能有编辑完但未提交至数据空的信息
void updateRowThroughExisitingAttribute(int, int);
//分页控制 //分页控制
void setPageSize(int); void setPageSize(int);
int pageSize() const; int pageSize() const;
@ -96,14 +92,14 @@ private:
//QSqlRecord record; //QSqlRecord record;
QVector<QVariant> values; QVector<QVariant> values;
QHash<int, bool> cellModified; //记录单元格是否被修改 QHash<int, bool> cellModified; //记录单元格是否被修改
EditState state = Clean; EditState state = EditState(Clean);
}; };
void iniDisplayField(); void iniDisplayField();
void getDataTypesFromDB(); void getDataTypesFromDB();
void loadPageData(); // 加载当前页数据 void loadPageData(); // 加载当前页数据
void updateTotalCount(); // 更新总记录数 void updateTotalCount(); // 更新总记录数
QList<RowData> filterRowsByEditState(EditState); QList<RowData> filterRowsByEditState(EditStateFlag);
int getDataTypeID(const QString&); int getDataTypeID(const QString&);
QString m_connection; QString m_connection;

View File

@ -5,6 +5,7 @@
#include <QTableView> #include <QTableView>
#include "global.h" #include "global.h"
#include "attributeTableModel.h" #include "attributeTableModel.h"
#include "attributeTableDelegate.h"
class QVBoxLayout; class QVBoxLayout;
class MultiLineHeaderView; class MultiLineHeaderView;
@ -21,6 +22,7 @@ public:
QTableView* view() const { return m_tableView; } QTableView* view() const { return m_tableView; }
AttributeTableModel* model() const { return m_attributeTableModel; } AttributeTableModel* model() const { return m_attributeTableModel; }
AttributeTableDelegate* delegate() const { return m_attributeTableDelegate; }
void active(); void active();
@ -31,6 +33,7 @@ private:
QTableView* m_tableView; QTableView* m_tableView;
AttributeTableModel* m_attributeTableModel; AttributeTableModel* m_attributeTableModel;
AttributeTableDelegate* m_attributeTableDelegate;
QVBoxLayout* m_vLayout; QVBoxLayout* m_vLayout;
MultiLineHeaderView* m_multiLinHeader; MultiLineHeaderView* m_multiLinHeader;

View File

@ -11,6 +11,18 @@ enum DialogState
DS_Edit DS_Edit
}; };
enum EditStateFlag
{
Clean = 0, // 二进制: 0b0000
Modified = 1 << 0, // 二进制: 0b0001
New = 1 << 1, // 二进制: 0b0010
Deleted = 1 << 2 // 二进制: 0b0100
};
//创建 QFlags 包装类型
Q_DECLARE_FLAGS(EditState, EditStateFlag)
//生成运算符重载
Q_DECLARE_OPERATORS_FOR_FLAGS(EditState)
struct DatabaseConfig struct DatabaseConfig
{ {
QString strID; //存储在配置文件时用作唯一标识 QString strID; //存储在配置文件时用作唯一标识

View File

@ -33,11 +33,15 @@ public:
protected: protected:
bool eventFilter(QObject*, QEvent*) override; bool eventFilter(QObject*, QEvent*) override;
void resizeEvent(QResizeEvent*) override;
private: private:
void initialize(); void initialize();
void showMaskLayer();
void hideMaskLayer();
Ui::MainWindow *ui; Ui::MainWindow *ui;
QWidget* m_maskLayer;
DatabaseManager* m_dbManager; DatabaseManager* m_dbManager;
DatabaseBrowser* m_dbBrowser; DatabaseBrowser* m_dbBrowser;
QSqlError m_lastSqlError; QSqlError m_lastSqlError;

49
include/messageBox.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef MESSAGEBOX_H
#define MESSAGEBOX_H
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui {
class messageDialog;
}
QT_END_NAMESPACE
enum MessageBoxType
{
t_information = 0,
t_question,
t_warning
};
// enum MessageBoxBtn
// {
// btn_Null = 0,
// btn_Yes,
// btn_No
// };
//extern MessageBoxBtn g_msgBoxBtn;
class MessageBox : public QDialog
{
Q_OBJECT
public:
MessageBox(QWidget *parent = nullptr);
~MessageBox();
static int show(MessageBoxType,const QString&,const QString&);
public slots:
void onBtnClicked_confirm();
void onBtnClicked_yes();
void onBtnClicked_no();
private:
void setType(MessageBoxType);
void setMessage(MessageBoxType,const QString&,const QString&);
Ui::messageDialog* ui;
};
#endif

View File

@ -35,8 +35,10 @@ public:
bool removeModel(const QString&, int); bool removeModel(const QString&, int);
//属性相关 //属性相关
int getAttributeCount(const QString&, int, int); int getAttributeCount(const QString&, int, int);
int getAllAttributeCount(const QString&);
bool getAttributeInfo(const QString&, const QString&, Attribute&); bool getAttributeInfo(const QString&, const QString&, Attribute&);
bool attributeTypeExistsInDB(const QString&, const QString&); int attributeTypeExistsInDB(const QString&, const QString&);
bool attributeTypeUseByModelGroup(const QString&, int, int, int);
bool batchInsertAttributes(const QString&, int, int, QList<Attribute>); bool batchInsertAttributes(const QString&, int, int, QList<Attribute>);
bool batchDeleteAttributes(const QString&, int, int, QList<int>); bool batchDeleteAttributes(const QString&, int, int, QList<int>);
bool batchUpdateAttributes(const QString&, int, int, QList<Attribute>); bool batchUpdateAttributes(const QString&, int, int, QList<Attribute>);

View File

@ -1,5 +1,7 @@
<RCC> <RCC>
<qresource prefix="img"> <qresource prefix="img">
<file>images/icon_search_white.png</file>
<file>images/icon_search.png</file>
<file>images/icon_refresh3_disable.png</file> <file>images/icon_refresh3_disable.png</file>
<file>images/icon_close_disable.png</file> <file>images/icon_close_disable.png</file>
<file>images/btn_close_pressed.png</file> <file>images/btn_close_pressed.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

View File

@ -0,0 +1,49 @@
#include "attributeSelector.h"
#include "ui_attributeSelector.h"
#include "mainwindow.h"
#include "attributeView.h"
AttributeSelector::AttributeSelector(const QString& connection, QWidget *parent)
: QWidget(parent)
, ui(new Ui::AttributeSelector)
, m_connection(connection)
{
ui->setupUi(this);
//隐藏一些功能按钮
ui->btnAdd->setVisible(false);
ui->btnRemove->setVisible(false);
ui->btnSave->setVisible(false);
ui->btnCancle->setVisible(false);
ModelAttributeGroup attributeGroup(-1, -1, "" ,"");
m_attributeView = new AttributeView(attributeGroup, ui->attributeViewContainer, connection);
ui->layoutTableView->addWidget(m_attributeView);
connect(ui->btnRefresh, &QPushButton::clicked, this, &AttributeSelector::onBtnClicked_refreshData);
}
AttributeSelector::~AttributeSelector()
{
delete ui;
}
void AttributeSelector::setMainWindow(MainWindow* window)
{
m_pMainWindow = window;
}
void AttributeSelector::onBtnClicked_refreshData()
{
}
void AttributeSelector::onSyncDataStatus(bool hasModifiedData, const PaginationInfo& paginationInfo)
{
ui->btnSave->setEnabled(!hasModifiedData);
ui->btnCancle->setEnabled(!hasModifiedData);
QString recordInfo = QString::fromWCharArray(L"共 %1 条记录").arg(paginationInfo.totalEntries);
ui->recordInfo->setText(recordInfo);
ui->lineEdit->setText(QString::number(paginationInfo.currentPage));
ui->lineEdit->setEnabled(true);
}

View File

@ -3,10 +3,12 @@
#include "attributeNamespace.h" #include "attributeNamespace.h"
#include "sqlQueryExecutor.h" #include "sqlQueryExecutor.h"
#include "ui_textEditWidget.h" #include "ui_textEditWidget.h"
//#include "messageBox.h"
#include <QSpinBox> #include <QSpinBox>
#include <QComboBox> #include <QComboBox>
#include <QLineEdit> #include <QLineEdit>
#include <QPainter> #include <QPainter>
#include <QTimer>
#include <QRegularExpressionValidator> #include <QRegularExpressionValidator>
TextEditWidget::TextEditWidget(QWidget* parent) TextEditWidget::TextEditWidget(QWidget* parent)
@ -76,6 +78,12 @@ void TextEditWidget::setErrorInfo(const QString& errorInfo)
ui->label->setText(errorInfo); ui->label->setText(errorInfo);
} }
void TextEditWidget::setFocusToTextEdit()
{
ui->plainTextEdit->setFocus();
ui->plainTextEdit->moveCursor(QTextCursor::End);
}
void TextEditWidget::onTextChanged() void TextEditWidget::onTextChanged()
{ {
ui->label->setText(m_promptString); ui->label->setText(m_promptString);
@ -161,23 +169,30 @@ QWidget* AttributeTableDelegate::createEditor(QWidget *parent, const QStyleOptio
if(dataCol == 0) //属性类型 if(dataCol == 0) //属性类型
{ {
TextEditWidget* textEditor = new TextEditWidget(parent); TextEditWidget* textEditor = new TextEditWidget(parent);
textEditor->setPrompt(QString::fromWCharArray(L"类型为英文")); textEditor->setPrompt(QString::fromWCharArray(L"类型必须为英文"));
textEditor->setRegularExpression("[A-Za-z0-9]"); textEditor->setRegularExpression("[A-Za-z0-9]");
connect(textEditor, &TextEditWidget::confirm, this, [=]{ connect(textEditor, &TextEditWidget::confirm, this, [=]{
QString strText = textEditor->editText(); /*QString strText = textEditor->editText();
bool exists = SqlQueryExecutor::instance().attributeTypeExistsInDB(m_connection, strText); int id = SqlQueryExecutor::instance().attributeTypeExistsInDB(m_connection, strText);
if(exists) if(id != -1)
textEditor->setErrorInfo(QString::fromWCharArray(L"该类型已存在")); textEditor->setErrorInfo(QString::fromWCharArray(L"该类型已存在"));
else else
{ {
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor); emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint); emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
} }*/
//判断放在setModelData函数中因为那里会先进行是否做内容改变的判断
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
}); });
connect(textEditor, &TextEditWidget::cancle, this, [=]{ connect(textEditor, &TextEditWidget::cancle, this, [=]{
//createEditor为const成员函数而closeEditor是QAbstractItemDelegate的非const信号在const成员函数中不能直接调用需要转换为非const指针 //createEditor为const成员函数而closeEditor是QAbstractItemDelegate的非const信号在const成员函数中不能直接调用需要转换为非const指针
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint); emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
}); });
//延迟获取焦点,防止可能因渲染未完成失效
QTimer::singleShot(10, this, [textEditor]() {
textEditor->setFocusToTextEdit();
});
return textEditor; return textEditor;
} }
else if(dataCol == 1 || dataCol == 4) //1-数据名称、4-默认值 else if(dataCol == 1 || dataCol == 4) //1-数据名称、4-默认值
@ -190,6 +205,10 @@ QWidget* AttributeTableDelegate::createEditor(QWidget *parent, const QStyleOptio
connect(textEditor, &TextEditWidget::cancle, this, [=]{ connect(textEditor, &TextEditWidget::cancle, this, [=]{
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint); emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
}); });
//延迟获取焦点,防止可能因渲染未完成失效
QTimer::singleShot(10, this, [textEditor]() {
textEditor->setFocusToTextEdit();
});
return textEditor; return textEditor;
} }
else if(dataCol == 2) //数据类型 else if(dataCol == 2) //数据类型
@ -227,7 +246,10 @@ QWidget* AttributeTableDelegate::createEditor(QWidget *parent, const QStyleOptio
void AttributeTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const void AttributeTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{ {
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor)) if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
{
textEditor->setEditText(index.data(Qt::DisplayRole).toString()); textEditor->setEditText(index.data(Qt::DisplayRole).toString());
//textEditor->setFocus();
}
else else
QStyledItemDelegate::setEditorData(editor, index); QStyledItemDelegate::setEditorData(editor, index);
} }
@ -254,6 +276,48 @@ void AttributeTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *m
if (newValue == oldValue) if (newValue == oldValue)
return; return;
int dataCol = index.column() - 1;
if(dataCol == 0) //属性类型 做预先判断1.是否以已在同组中 2.是否已被创建
{
auto attributeTableModel = qobject_cast<AttributeTableModel*>(model);
auto textEditor = qobject_cast<TextEditWidget*>(editor);
if(attributeTableModel && textEditor)
{
QString strText = textEditor->editText();
int id = SqlQueryExecutor::instance().attributeTypeExistsInDB(m_connection, strText);
//1.是否以已在同组中(要同时从内存和数据库中都进行查找,避免遗漏已创建但未提交的数据)
bool existsInCurrentGropu = attributeTableModel->attributeTypeExistsInCurrentGroup(id, strText);
if(existsInCurrentGropu)
{
emit const_cast<AttributeTableDelegate*>(this)->showMessage(type_information, QString::fromWCharArray(L"提示"),
QString::fromWCharArray(L"该类型属性已在当前组中存在"));
return;
}
//2.是否已被创建
if(id != -1)
{
/*int result = MessageBox::show(t_question, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"该类型属性已创建,是否直接载入当前数据"));
if(result == QDialog::Accepted)
{
auto attributeTableModel = qobject_cast<AttributeTableModel*>(model);
attributeTableModel->updateRowThroughExisitingAttribute(index.row(), id);
return;
}
else
return;*/
emit const_cast<AttributeTableDelegate*>(this)->showMessage(type_question, QString::fromWCharArray(L"提示"),
QString::fromWCharArray(L"该类型属性已创建,是否直接载入当前数据"));
if(g_msgDlgBtn == btn_Yes)
{
attributeTableModel->updateRowThroughExisitingAttribute(index.row(), id);
return;
}
else
return;
}
}
}
model->setData(index, newValue, Qt::EditRole); model->setData(index, newValue, Qt::EditRole);
} }

View File

@ -27,7 +27,7 @@ QModelIndex AttributeTableModel::index(int row, int column, const QModelIndex& p
return QModelIndex(); return QModelIndex();
int dataCol = column - 1; int dataCol = column - 1;
if(dataCol >= m_displayField.count()) if(dataCol > m_displayField.count())
return QModelIndex(); return QModelIndex();
return createIndex(row, column); return createIndex(row, column);
@ -59,6 +59,9 @@ QVariant AttributeTableModel::data(const QModelIndex& index, int role) const
case New: case New:
mark = "+"; mark = "+";
break; break;
case New | Modified:
mark = "+";
break;
case Deleted: case Deleted:
mark = "-"; mark = "-";
break; break;
@ -133,7 +136,11 @@ bool AttributeTableModel::setData(const QModelIndex &index, const QVariant &valu
else else
modifiedRow.values[dataCol] = value; modifiedRow.values[dataCol] = value;
modifiedRow.cellModified[dataCol] = true; //标记单元格 modifiedRow.cellModified[dataCol] = true; //标记单元格
modifiedRow.state = (modifiedRow.state == New) ? New : Modified; const int attributeID = modifiedRow.values.last().toInt();
if(attributeID == -1) //纯新建
modifiedRow.state = (modifiedRow.state == New) ? New : Modified;
else
modifiedRow.state = (modifiedRow.state == New) ? modifiedRow.state |= Modified : Modified; //新建时从已有数据进行的加载,然后再次编辑就会变为叠加态
m_modifiedRows[globalRow] = modifiedRow; m_modifiedRows[globalRow] = modifiedRow;
m_currentPageData[row] = modifiedRow; m_currentPageData[row] = modifiedRow;
@ -173,13 +180,67 @@ int AttributeTableModel::columnCount(const QModelIndex &) const
Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const
{ {
QModelIndex numberIndex = createIndex(index.row(), 0);
QString text = numberIndex.data(Qt::DisplayRole).toString();
Qt::ItemFlags flags = QAbstractTableModel::flags(index); Qt::ItemFlags flags = QAbstractTableModel::flags(index);
if (index.column() != 0 && !text.contains("-")) //行号列和处于删除状态的item不能编辑 if(m_modelAttributeGroup.modelID < 0) //表示当前加载数据对象是所有属性前端UI是属性选择器选择器为非可编辑状态
flags = flags | Qt::ItemIsEditable; return flags;
return flags; else
{
QModelIndex numberIndex = createIndex(index.row(), 0);
QString text = numberIndex.data(Qt::DisplayRole).toString();
if (index.column() != 0 && !text.contains("-")) //行号列和处于删除状态的item不能编辑
flags = flags | Qt::ItemIsEditable;
return flags;
}
}
bool AttributeTableModel::attributeTypeExistsInCurrentGroup(int id, const QString& type)
{
//先查找内存数据
for(RowData rowData : m_currentPageData)
{
if(rowData.values[0] == type)
return true;
}
//再从数据库中查找,因为内存只存储当前页的数据
if(id != -1) //说明是之前创建过的属性(数据库中已存在)
return SqlQueryExecutor::instance().attributeTypeUseByModelGroup(m_connection, id, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID);
return false;
}
void AttributeTableModel::updateRowThroughExisitingAttribute(int row, int attributeID)
{
//qDebug() << "row:" << row << " attributeID:" << attributeID;
QStringList columns;
for(int i = 0; i < m_displayField.count(); i++)
columns << m_displayField.at(i).originalName;
Attribute attribute;
attribute.id = attributeID;
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
{
RowData updateRow = m_currentPageData[row];
//updateRow.values.resize(m_displayField.count() + 1);
updateRow.values[0] = attribute.type;
updateRow.values[1] = attribute.name;
updateRow.values[2] = attribute.dataTypeID;
updateRow.values[3] = attribute.dataLength;
updateRow.values[4] = attribute.defaultValue;
updateRow.values[5] = attribute.id;//将id存入最后不做显示删除或者修改数据的时候会用到
for(int i = 0; i < m_displayField.count(); i++)
updateRow.cellModified[i] = true; //标记单元格
updateRow.state = (updateRow.state == New) ? New : Modified;
m_currentPageData[row] = updateRow;
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
m_modifiedRows[globalRow] = updateRow;
QModelIndex topLeft = index(row, 1, QModelIndex());
QModelIndex bottomRight = index(row, m_displayField.count(), QModelIndex());
emit dataChanged(topLeft, bottomRight);
}
} }
void AttributeTableModel::iniDisplayField() void AttributeTableModel::iniDisplayField()
@ -263,38 +324,64 @@ void AttributeTableModel::loadPageData()
beginResetModel(); beginResetModel();
QString strSQL = QString("SELECT attribute_id FROM basic.model_attribute WHERE model_type_id = %1 AND attribute_group_id = %2 LIMIT %3 OFFSET %4") QStringList columns;
.arg(m_modelAttributeGroup.modelID) for(int i = 0; i < m_displayField.count(); i++)
.arg(m_modelAttributeGroup.groupID) columns << m_displayField.at(i).originalName;
.arg(m_paginationInfo.entriesPerPage)
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
try
{
QStringList columns;
for(int i = 0; i < m_displayField.count(); i++)
columns << m_displayField.at(i).originalName;
QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL); if(m_modelAttributeGroup.modelID < 0) //表示当前加载数据对象是所有属性
while(query.next()) {
columns.append("id"); //将id放到最后和按照具体模型、具体属性组读取数据方式时逻辑统一具体见下面分支逻辑
QString strSQL = QString("SELECT %1 FROM basic.attribute LIMIT %2 OFFSET %3")
.arg(columns.join(", "))
.arg(m_paginationInfo.entriesPerPage)
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
try
{ {
Attribute attribute; QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL);
attribute.id = query.value(0).toInt(); while(query.next())
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
{ {
RowData data; RowData data;
data.values.append(attribute.type); for(int i = 0; i < columns.count(); i++)
data.values.append(attribute.name); data.values.append(query.value(i));
data.values.append(attribute.dataTypeID);
data.values.append(attribute.dataLength);
data.values.append(attribute.defaultValue);
data.values.append(attribute.id);//将id存入最后不做显示删除或者修改数据的时候会用到
m_currentPageData.append(data); m_currentPageData.append(data);
} }
} }
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性信息失败(所有属性)。"));
}
} }
catch (const DatabaseException& e) else //按具体模型的具体属性组读取数据
{ {
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性信息失败。modelID:%1, groupID:%2").arg(m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID)); QString strSQL = QString("SELECT attribute_id FROM basic.model_attribute WHERE model_type_id = %1 AND attribute_group_id = %2 LIMIT %3 OFFSET %4")
.arg(m_modelAttributeGroup.modelID)
.arg(m_modelAttributeGroup.groupID)
.arg(m_paginationInfo.entriesPerPage)
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
try
{
QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL);
while(query.next())
{
Attribute attribute;
attribute.id = query.value(0).toInt();
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
{
RowData data;
data.values.append(attribute.type);
data.values.append(attribute.name);
data.values.append(attribute.dataTypeID);
data.values.append(attribute.dataLength);
data.values.append(attribute.defaultValue);
data.values.append(attribute.id);//将id存入最后不做显示删除或者修改数据的时候会用到
m_currentPageData.append(data);
}
}
}
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性信息失败。modelID:%1, groupID:%2").arg(m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID));
}
} }
endResetModel(); endResetModel();
@ -368,15 +455,18 @@ void AttributeTableModel::updateTotalCount()
return; return;
}*/ }*/
m_paginationInfo.totalEntries = SqlQueryExecutor::instance().getAttributeCount(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID); if(m_modelAttributeGroup.modelID < 0)
m_paginationInfo.totalEntries = SqlQueryExecutor::instance().getAllAttributeCount(m_connection);
else
m_paginationInfo.totalEntries = SqlQueryExecutor::instance().getAttributeCount(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID);
} }
QList<AttributeTableModel::RowData> AttributeTableModel::filterRowsByEditState(EditState state) QList<AttributeTableModel::RowData> AttributeTableModel::filterRowsByEditState(EditStateFlag state)
{ {
QList<RowData> result; QList<RowData> result;
for(auto it = m_modifiedRows.begin(); it != m_modifiedRows.end(); it++) for(auto it = m_modifiedRows.begin(); it != m_modifiedRows.end(); it++)
{ {
if(it.value().state == state) if(it.value().state.testFlag(state))
result.append(it.value()); result.append(it.value());
} }
return result; return result;
@ -415,7 +505,8 @@ void AttributeTableModel::insertRecord(int row)
RowData newRow; RowData newRow;
newRow.state = New; newRow.state = New;
newRow.values.resize(m_displayField.count()); newRow.values.resize(m_displayField.count() + 1); //多出一个位置给id
newRow.values.last() = -1;
//newRow.values[2] = 11; //newRow.values[2] = 11;
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row; int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
@ -486,7 +577,10 @@ void AttributeTableModel::submitChanges()
if(rowData.values.value(4).isValid()) if(rowData.values.value(4).isValid())
defaultValue = rowData.values.value(4).toString(); defaultValue = rowData.values.value(4).toString();
insertAttributes.emplace_back(-1, name, type, dataTypeID, dataLength, defaultValue); int id = -1;
if(rowData.values.size() == m_displayField.count() +1)
id = rowData.values.value(m_displayField.count()).toInt();
insertAttributes.emplace_back(id, name, type, dataTypeID, dataLength, defaultValue);
} }
insertCompleted = SqlQueryExecutor::instance().batchInsertAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, insertAttributes); insertCompleted = SqlQueryExecutor::instance().batchInsertAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, insertAttributes);
} }

View File

@ -14,13 +14,14 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
m_tableView = new QTableView(this); m_tableView = new QTableView(this);
m_tableView->setStyleSheet("QTableView::item{padding-left:5px;} QTableView::item:selected{border:1px solid rgb(70,130,180);}"); m_tableView->setStyleSheet("QTableView::item{padding-left:5px;} QTableView::item:selected{border:1px solid rgb(70,130,180);}");
m_tableView->verticalHeader()->setVisible(false); m_tableView->verticalHeader()->setVisible(false);
//m_tableView->setTabKeyNavigation(false); //关闭tab键导航 m_tableView->setFocusPolicy(Qt::NoFocus); //避免视图抢Editor的焦点
m_tableView->setTabKeyNavigation(false); //关闭tab键导航
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable); m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
m_tableView->setModel(m_attributeTableModel); m_tableView->setModel(m_attributeTableModel);
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_connection, m_tableView); m_attributeTableDelegate = new AttributeTableDelegate(m_tableView, m_connection, m_tableView);
m_tableView->setItemDelegate(delegate); m_tableView->setItemDelegate(m_attributeTableDelegate);
//自定义表头 //自定义表头
m_multiLinHeader = new MultiLineHeaderView(Qt::Horizontal, this); m_multiLinHeader = new MultiLineHeaderView(Qt::Horizontal, this);

View File

@ -0,0 +1,62 @@
#include "attributeView.h"
#include "attributeTableDelegate.h"
#include "multiLineHeaderView.h"
#include <QHeaderView>
#include <QVBoxLayout>
#include <QTimer>
AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWidget* parent, const QString& connection, const QString& tableName)
: QWidget(parent)
, m_connection(connection)
, m_attributeTable(tableName)
, m_modelAttributeGroup(modelAttributeGroup)
{
m_tableView = new QTableView(this);
m_tableView->setStyleSheet("QTableView::item{padding-left:5px;} QTableView::item:selected{border:1px solid rgb(70,130,180);}");
m_tableView->verticalHeader()->setVisible(false);
m_tableView->setTabKeyNavigation(false); //关闭tab键导航
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
m_tableView->setModel(m_attributeTableModel);
m_attributeTableDelegate = new AttributeTableDelegate(m_tableView, m_connection, m_tableView);
m_tableView->setItemDelegate(m_attributeTableDelegate);
//自定义表头
m_multiLinHeader = new MultiLineHeaderView(Qt::Horizontal, this);
QColor bg(246, 246, 246);
QColor border(228, 228, 228);
m_multiLinHeader->setBackgroundColor(bg);
m_multiLinHeader->setBorderColor(border);
//主标题加粗展示
for(int i =0; i < m_attributeTableModel->columnCount(); i++)
{
HeaderLineStyle mainTitleStyle;
mainTitleStyle.font.setBold(true);
m_multiLinHeader->setSectionLineStyle(i, 0, mainTitleStyle);
HeaderLineStyle subTitleStyle;
//subTitleStyle.font.setPointSize(8);
m_multiLinHeader->setSectionLineStyle(i, 1, subTitleStyle);
}
m_tableView->setHorizontalHeader(m_multiLinHeader);
//除了第一列其余列恢复可以手动调整模式
QTimer::singleShot(1000, this, [=](){
for(int i = 1; i < m_multiLinHeader->count(); i++)
m_multiLinHeader->setSectionResizeMode(i, QHeaderView::Interactive);
});
m_vLayout = new QVBoxLayout(this);
m_vLayout->setSpacing(0);
m_vLayout->setContentsMargins(0, 0, 0, 0);
m_vLayout->addWidget(m_tableView);
this->setLayout(m_vLayout);
}
AttributeView::~AttributeView()
{}
void AttributeView::active()
{
m_attributeTableModel->triggerSyncSignal();
}

View File

@ -55,6 +55,7 @@ void DatabaseBrowser::addTab_attribute(const QString& connection, ModelAttribute
AttributeView* view = new AttributeView(attributeGroup, ui->tabWidget, connection); AttributeView* view = new AttributeView(attributeGroup, ui->tabWidget, connection);
connect(view->model(), &AttributeTableModel::showMessage, this, &DatabaseBrowser::onShowMessage); connect(view->model(), &AttributeTableModel::showMessage, this, &DatabaseBrowser::onShowMessage);
connect(view->model(), &AttributeTableModel::syncDataStatus, this, &DatabaseBrowser::onSyncDataStatus); connect(view->model(), &AttributeTableModel::syncDataStatus, this, &DatabaseBrowser::onSyncDataStatus);
connect(view->delegate(), &AttributeTableDelegate::showMessage, this, &DatabaseBrowser::onShowMessage);
index = ui->tabWidget->addTab(view, QIcon(":/img/images/icon_hierarchy.png"), tabText); index = ui->tabWidget->addTab(view, QIcon(":/img/images/icon_hierarchy.png"), tabText);
//添加自定义按钮 //添加自定义按钮
/*QPushButton* closeBtn = new QPushButton(""); /*QPushButton* closeBtn = new QPushButton("");

View File

@ -16,6 +16,7 @@
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, m_maskLayer(nullptr)
, m_dbManager(nullptr) , m_dbManager(nullptr)
, m_dbBrowser(nullptr) , m_dbBrowser(nullptr)
, m_pMessageDialog(nullptr) , m_pMessageDialog(nullptr)
@ -50,6 +51,13 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event)
return QObject::eventFilter(obj, event); return QObject::eventFilter(obj, event);
} }
void MainWindow::resizeEvent(QResizeEvent* event)
{
if(m_maskLayer)
m_maskLayer->setGeometry(0, 0, width(), height());
QWidget::resizeEvent(event);
}
void MainWindow::initialize() void MainWindow::initialize()
{ {
connect(ui->connectAction, &QAction::triggered, this, &MainWindow::onActionTrigger_connect); connect(ui->connectAction, &QAction::triggered, this, &MainWindow::onActionTrigger_connect);
@ -60,6 +68,11 @@ void MainWindow::initialize()
connect(&SqlQueryExecutor::instance(), &SqlQueryExecutor::errorOccurred, this, &MainWindow::onSIG_errorFormSQLExecutor); connect(&SqlQueryExecutor::instance(), &SqlQueryExecutor::errorOccurred, this, &MainWindow::onSIG_errorFormSQLExecutor);
m_maskLayer = new QWidget(this);
//m_maskLayer->setAttribute(Qt::WA_TransparentForMouseEvents, true);
m_maskLayer->setStyleSheet("background:rgba(112,128,144,180);");
m_maskLayer->hide();
m_dbManager = new DatabaseManager(this); m_dbManager = new DatabaseManager(this);
connect(m_dbManager, &DatabaseManager::errorOccurred, this, &MainWindow::onSIG_errorFromDBManger); connect(m_dbManager, &DatabaseManager::errorOccurred, this, &MainWindow::onSIG_errorFromDBManger);
connect(m_dbManager, &DatabaseManager::connectionStatusChanged, this, &MainWindow::onSIG_connectionStatusChanged); connect(m_dbManager, &DatabaseManager::connectionStatusChanged, this, &MainWindow::onSIG_connectionStatusChanged);
@ -90,6 +103,18 @@ void MainWindow::initialize()
// ui->splitter->setStretchFactor(1, 7); // ui->splitter->setStretchFactor(1, 7);
} }
void MainWindow::showMaskLayer()
{
m_maskLayer->setGeometry(0, 0, width(), height());
m_maskLayer->raise();
m_maskLayer->show();
}
void MainWindow::hideMaskLayer()
{
m_maskLayer->hide();
}
void MainWindow::showMessageDialog(MessageDialogType type,const QString& strTitle,const QString& strContent) void MainWindow::showMessageDialog(MessageDialogType type,const QString& strTitle,const QString& strContent)
{ {
if(m_pMessageDialog == nullptr) if(m_pMessageDialog == nullptr)
@ -107,7 +132,10 @@ void MainWindow::showMessageDialog(MessageDialogType type,const QString& strTitl
// m_pMessageDialog->exec(); // m_pMessageDialog->exec();
// else // else
// m_pMessageDialog->show(); // m_pMessageDialog->show();
//showMaskLayer();
m_pMessageDialog->exec(); m_pMessageDialog->exec();
//hideMaskLayer();
} }
void MainWindow::hideMessageDialog() void MainWindow::hideMessageDialog()
{ {
@ -148,7 +176,10 @@ void MainWindow::onActionTrigger_connect()
// QPoint centerPos = this->mapToGlobal(this->rect().center()); // QPoint centerPos = this->mapToGlobal(this->rect().center());
// centerPos -= QPoint(m_pConnectionDialog->width()/2, m_pConnectionDialog->height()/2); // centerPos -= QPoint(m_pConnectionDialog->width()/2, m_pConnectionDialog->height()/2);
// m_pConnectionDialog->move(centerPos); // m_pConnectionDialog->move(centerPos);
m_pConnectionDialog->show();
//showMaskLayer();
m_pConnectionDialog->exec();
//hideMaskLayer();
} }
void MainWindow::onActionTrigger_disconnect() void MainWindow::onActionTrigger_disconnect()
{ {
@ -173,7 +204,10 @@ void MainWindow::onActionTrigger_addModel()
int nY = this->geometry().y() + (this->height() - m_pModelInfoDialog->height()) * 0.5; int nY = this->geometry().y() + (this->height() - m_pModelInfoDialog->height()) * 0.5;
m_pModelInfoDialog->move(nX, nY); m_pModelInfoDialog->move(nX, nY);
m_pModelInfoDialog->setState(DS_New); m_pModelInfoDialog->setState(DS_New);
//showMaskLayer();
m_pModelInfoDialog->exec(); m_pModelInfoDialog->exec();
//hideMaskLayer();
} }
void MainWindow::onActionTrigger_removeModel() void MainWindow::onActionTrigger_removeModel()
{ {

87
source/messageBox.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "messageBox.h"
#include "ui_messageDialog.h"
//MessageBoxBtn g_msgBoxBtn = btn_Null;
MessageBox::MessageBox(QWidget *parent)
: QDialog(parent)
, ui(new Ui::messageDialog)
{
ui->setupUi(this);
if(QSysInfo::kernelType() == "linux")
{
//Linux下默认的Qt::Dialog即使有父窗口也无法按照子窗口的行为进行展示并且最大、最小按钮不好关闭因此需要去掉Dialog属性随之而来的问题是模态无法起作用
setWindowFlags(windowFlags() & ~Qt::Dialog);
setStyleSheet("QDialog{border: 1px solid rgb(205,205,205);border-radius:5px;background-color:rgb(245,245,245);background-color:rgb(245,245,245);}");
}
else
{
setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);//去掉关闭按钮和图标
setFixedSize(width(), height()); //不可缩放
}
connect(ui->btnConfrim, SIGNAL(clicked()), this, SLOT(onBtnClicked_confirm()));
connect(ui->btnYes, SIGNAL(clicked()), this, SLOT(onBtnClicked_yes()));
connect(ui->btnNo, SIGNAL(clicked()), this, SLOT(onBtnClicked_no()));
}
MessageBox::~MessageBox()
{
delete ui;
}
void MessageBox::setType(MessageBoxType type)
{
if(type == t_information)
{
ui->typeLabel->setStyleSheet("border-image: url(:/img/images/icon_information.png);");
ui->stackedWidget->setCurrentIndex(0);
}
else if(type == t_question)
{
ui->typeLabel->setStyleSheet("border-image: url(:/img/images/icon_question.png);");
ui->stackedWidget->setCurrentIndex(1);
}
else if(type == t_warning)
{
ui->typeLabel->setStyleSheet("border-image: url(:/img/images/icon_no.png);");
ui->stackedWidget->setCurrentIndex(0);
}
}
void MessageBox::setMessage(MessageBoxType type,const QString& strTitle,const QString& strContent)
{
setType(type);
ui->labelTitle->setText(strTitle);
setWindowTitle(strTitle);
ui->labelContent->setText(strContent);
}
int MessageBox::show(MessageBoxType type,const QString& strTitle,const QString& strContent)
{
MessageBox msgBox;
msgBox.setMessage(type, strTitle, strContent);
return msgBox.exec();
}
void MessageBox::onBtnClicked_confirm()
{
// hide();
accept();
}
void MessageBox::onBtnClicked_yes()
{
// g_msgDlgBtn = btn_Yes;
// hide();
accept();
}
void MessageBox::onBtnClicked_no()
{
// g_msgDlgBtn = btn_No;
// hide();
reject();
}

View File

@ -446,6 +446,24 @@ int SqlQueryExecutor::getAttributeCount(const QString& connectionName, int model
return count; return count;
} }
int SqlQueryExecutor::getAllAttributeCount(const QString& connectionName)
{
int count = 0;
QString strSQL = QString("SELECT COUNT(*) FROM basic.attribute");
try
{
QSqlQuery query = executeSQL(connectionName, strSQL);
if(query.next())
count = query.value(0).toInt();
}
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性数量失败"));
}
return count;
}
bool SqlQueryExecutor::getAttributeInfo(const QString& connectionName, const QString& columns, Attribute& attribute) bool SqlQueryExecutor::getAttributeInfo(const QString& connectionName, const QString& columns, Attribute& attribute)
{ {
QString strSQL = QString("SELECT %1 FROM basic.attribute WHERE id = %2").arg(columns).arg(attribute.id); QString strSQL = QString("SELECT %1 FROM basic.attribute WHERE id = %2").arg(columns).arg(attribute.id);
@ -472,21 +490,41 @@ bool SqlQueryExecutor::getAttributeInfo(const QString& connectionName, const QSt
return true; return true;
} }
bool SqlQueryExecutor::attributeTypeExistsInDB(const QString& connectionName, const QString& type) int SqlQueryExecutor::attributeTypeExistsInDB(const QString& connectionName, const QString& type)
{ {
bool exists = false; int id = -1;
QString strSQL = "SELECT id FROM basic.attribute WHERE attribute = \'" + type + "\'"; QString strSQL = "SELECT id FROM basic.attribute WHERE attribute = \'" + type + "\'";
try try
{ {
QSqlQuery query = executeSQL(connectionName, strSQL); QSqlQuery query = executeSQL(connectionName, strSQL);
if(query.next()) if(query.next())
exists = true; id = query.value(0).toInt();
} }
catch (const DatabaseException& e) catch (const DatabaseException& e)
{ {
exists = true; id = -1;
} }
return exists; return id;
}
bool SqlQueryExecutor::attributeTypeUseByModelGroup(const QString& connectionName, int attributeID, int modelID, int groupID)
{
QString strSQL = "SELECT id FROM basic.model_attribute WHERE model_type_id = :modelID AND attribute_group_id = :groupID AND attribute_id = :attributeID";
QVariantHash params;
params.insert(":modelID", modelID);
params.insert(":groupID", groupID);
params.insert(":attributeID", attributeID);
try
{
QSqlQuery query = executeSQL(connectionName, strSQL, params);
if(query.next())
return true;
}
catch (const DatabaseException& e)
{
return false;
}
return false;
} }
bool SqlQueryExecutor::batchInsertAttributes(const QString& connectionName, int modelID, int attributeGroupID, QList<Attribute> attributes) bool SqlQueryExecutor::batchInsertAttributes(const QString& connectionName, int modelID, int attributeGroupID, QList<Attribute> attributes)
@ -509,6 +547,12 @@ bool SqlQueryExecutor::batchInsertAttributes(const QString& connectionName, int
QList<qint64> attributeIDList; QList<qint64> attributeIDList;
for(const Attribute& attribute : attributes) for(const Attribute& attribute : attributes)
{ {
if(attribute.id != -1) //新建条目是通过选择已有的记录完成,此类不再做重复插入
{
attributeIDList.append(attribute.id);
continue;
}
qint64 attributeID = QDateTime::currentDateTime().toMSecsSinceEpoch(); qint64 attributeID = QDateTime::currentDateTime().toMSecsSinceEpoch();
//先向model_type中插入一条记录 //先向model_type中插入一条记录
QString strSQL = "INSERT INTO basic.attribute (attribute, attribute_name, data_type_id, length_precision, default_value) VALUES " QString strSQL = "INSERT INTO basic.attribute (attribute, attribute_name, data_type_id, length_precision, default_value) VALUES "

713
ui/attributeSelector.ui Normal file
View File

@ -0,0 +1,713 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AttributeSelector</class>
<widget class="QWidget" name="AttributeSelector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1111</width>
<height>481</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="searchBar" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>36</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QWidget #searchBar
{
background-color: rgb(243, 243, 243);
}
QLineEdit
{
border:1px solid rgb(210,210,210);
border-radius:3px;
}
</string>
</property>
<widget class="QLabel" name="label_type">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>属性类别:</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_type">
<property name="geometry">
<rect>
<x>80</x>
<y>8</y>
<width>113</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_name">
<property name="geometry">
<rect>
<x>280</x>
<y>8</y>
<width>113</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_name">
<property name="geometry">
<rect>
<x>220</x>
<y>10</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>属性名称:</string>
</property>
</widget>
<widget class="QPushButton" name="btnSearch">
<property name="geometry">
<rect>
<x>420</x>
<y>5</y>
<width>61</width>
<height>26</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton
{
color: rgb(250, 250, 250);
font: 9pt;
border:0px;
border-radius:5px;
background-color:rgb(67,160,249);
}
QPushButton:hover
{
background-color:rgb(55,131,204);
}
QPushButton:pressed
{
background-color:rgb(67,160,249);
}</string>
</property>
<property name="text">
<string>查找</string>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_search_white.png</normaloff>:/img/images/icon_search_white.png</iconset>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="attributeViewContainer" native="true">
<layout class="QVBoxLayout" name="layoutTableView">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="toolBar" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>31</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>31</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QWidget #toolBar
{
background-color: rgb(243, 243, 243);
}
QPushButton
{
border: 0px solid rgb(205,205,205);
border-radius:0px;
}
QPushButton:hover
{
background-color:rgba(70,130,180,35);
}
QPushButton:pressed
{
background-color:rgba(70,130,180,65);
}</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetNoConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="recordControlPanel" native="true">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<widget class="QPushButton" name="btnAdd">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>添加</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_plus.png</normaloff>
<disabledoff>:/img/images/icon_plus_disable.png</disabledoff>:/img/images/icon_plus.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnRemove">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>36</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>删除</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_subtract.png</normaloff>
<disabledoff>:/img/images/icon_subtract_disable.png</disabledoff>:/img/images/icon_subtract.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnSave">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>62</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>提交修改</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_done.png</normaloff>
<disabledoff>:/img/images/icon_done_disable.png</disabledoff>:/img/images/icon_done.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnCancle">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>88</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>取销修改</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_close.png</normaloff>
<disabledoff>:/img/images/icon_close_disable.png</disabledoff>:/img/images/icon_close.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnRefresh">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>114</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>刷新</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_refresh3.png</normaloff>
<disabledoff>:/img/images/icon_refresh3_disable.png</disabledoff>:/img/images/icon_refresh3.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>727</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="pageControlPanel" native="true">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<widget class="QLineEdit" name="lineEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>210</x>
<y>5</y>
<width>41</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>41</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>41</width>
<height>21</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">border:0px;
background-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>1</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="btnFirstPage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>170</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>第一页</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_first.png</normaloff>:/img/images/icon_first.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnLastPage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>272</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>最后一页</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_last.png</normaloff>:/img/images/icon_last.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnPreviousPage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>190</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>上一页</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_previous.png</normaloff>:/img/images/icon_previous.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="btnNextPage">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>252</x>
<y>5</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>下一页</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_next.png</normaloff>:/img/images/icon_next.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
<widget class="QLabel" name="recordInfo">
<property name="geometry">
<rect>
<x>12</x>
<y>5</y>
<width>151</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resource/PowerModeler.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -64,7 +64,7 @@
<string notr="true">font: 10pt;</string> <string notr="true">font: 10pt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>获取属性组别信息失败,详情可见日志文件</string> <string>该类型已存在,是否读取数据载入详细数据</string>
</property> </property>
</widget> </widget>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">

View File

@ -64,7 +64,7 @@ background-color:rgb(255,255,255);
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit"> <widget class="QPlainTextEdit" name="plainTextEdit">
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::FocusPolicy::ClickFocus</enum> <enum>Qt::FocusPolicy::StrongFocus</enum>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background-color: transparent; <string notr="true">background-color: transparent;
@ -98,7 +98,7 @@ padding:2px;</string>
<number>0</number> <number>0</number>
</property> </property>
<property name="leftMargin"> <property name="leftMargin">
<number>10</number> <number>5</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
@ -132,14 +132,14 @@ font: 8pt &quot;Microsoft YaHei UI&quot;;</string>
<widget class="QPushButton" name="btnCancle"> <widget class="QPushButton" name="btnCancle">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>51</width> <width>41</width>
<height>26</height> <height>21</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>51</width> <width>41</width>
<height>26</height> <height>21</height>
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
@ -166,14 +166,14 @@ QPushButton:pressed
<widget class="QPushButton" name="btnConfirm"> <widget class="QPushButton" name="btnConfirm">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>51</width> <width>41</width>
<height>26</height> <height>21</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>51</width> <width>41</width>
<height>26</height> <height>21</height>
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">