完成属性编辑时自定义编辑控件的加载和上下游逻辑

This commit is contained in:
duanshengchao 2025-04-08 20:02:38 +08:00
parent 32e7e649ae
commit ac9858146f
13 changed files with 597 additions and 35 deletions

View File

@ -33,6 +33,7 @@ set(H_HEADER_FILES
include/multiLineHeaderView.h
include/modelInfoEditDialog.h
include/sqlQueryExecutor.h
include/attributeNamespace.h
include/attributeTableModel.h
include/attributeTableDelegate.h
include/attributeView.h
@ -67,6 +68,7 @@ set(UI_FILES
ui/connectionDialog.ui
ui/messageDialog.ui
ui/modelInfoEditDialog.ui
ui/textEditWidget.ui
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 13.0.2, 2025-04-03T14:28:51. -->
<!-- Written by QtCreator 13.0.2, 2025-04-03T18:33:56. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@ -0,0 +1,19 @@
#ifndef ATTRIBUTENAMESPACE_H
#define ATTRIBUTENAMESPACE_H
namespace AttributeEidt
{
enum DataType
{
ENUM = 0,
TEXT
};
enum DataRole
{
EditStatus = 100,
DataType
};
}
#endif

View File

@ -4,22 +4,64 @@
#include <QStyledItemDelegate>
#include <QTableView>
QT_BEGIN_NAMESPACE
namespace Ui {
class TextEditWidget;
}
QT_END_NAMESPACE
class TextEditWidget : public QWidget {
Q_OBJECT
public:
explicit TextEditWidget(QWidget* parent = nullptr);
~TextEditWidget();
QString editText();
void setEditText(const QString&);
void setPrompt(const QString&);
void setRegularExpression(const QString&);
void setErrorInfo(const QString&);
signals:
void confirm();
void cancle();
protected:
//bool eventFilter(QObject*, QEvent*) override;
private slots:
void onTextChanged();
void onBtnClicked_confirm();
void onBtnClicked_cancle();
private:
Ui::TextEditWidget* ui;
QString m_promptString; //提示字符
QString m_patternString; //正则表达式的模式字符
QRegularExpression m_regExp;
};
class AttributeTableDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit AttributeTableDelegate(QTableView* view, QObject* parent = nullptr);
explicit AttributeTableDelegate(QTableView* view, const QString& connection = "", QObject* parent = nullptr);
~AttributeTableDelegate();
/*QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const override;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const override;
//void destroyEditor(QWidget* editor, const QModelIndex& index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;*/
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
bool isEnumType(const QModelIndex&) const;
QString m_connection;
QTableView* m_tableView;
};

View File

@ -32,6 +32,13 @@ public:
Deleted
};
struct DataType //数据类型
{
int id;
QString type;
QString db; //为哪个数据库的可用类型
};
explicit AttributeTableModel(const ModelAttributeGroup& modelAttributeGroup
, QObject* parent = nullptr
, const QString& connection = ""
@ -68,6 +75,8 @@ public:
//展示列控制
//void setVisibleColumns(const QStringList& columns);
//others
QMap<int, DataType> getDataTypes() {return m_dataTypes;}
void triggerSyncSignal();
signals:
@ -89,18 +98,12 @@ private:
EditState state = Clean;
};
struct DataType //数据类型
{
int id;
QString type;
QString db; //为哪个数据库的可用类型
};
void iniDisplayField();
void getDataTypes();
void getDataTypesFromDB();
void loadPageData(); // 加载当前页数据
void updateTotalCount(); // 更新总记录数
QList<RowData> filterRowsByEditState(EditState);
int getDataTypeID(const QString&);
QString m_connection;
QString m_tableName;
@ -111,6 +114,7 @@ private:
QList<RowData> m_currentPageData;
QHash<int, RowData> m_modifiedRows; //key:global row number
QMap<int, DataType> m_dataTypes;
QHash<QString, int> m_reversalDataTypes; //dataType的反转用来通过名称快速查找对应id
};
#endif //ATTRIBUTETABLEMODEL_H

View File

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

View File

@ -1,9 +1,117 @@
#include "attributeTableDelegate.h"
#include "attributeTableModel.h"
#include "attributeNamespace.h"
#include "sqlQueryExecutor.h"
#include "ui_textEditWidget.h"
#include <QSpinBox>
#include <QComboBox>
#include <QLineEdit>
#include <QPainter>
#include <QRegularExpressionValidator>
AttributeTableDelegate::AttributeTableDelegate(QTableView* view, QObject *parent)
TextEditWidget::TextEditWidget(QWidget* parent)
: QWidget(parent), ui(new Ui::TextEditWidget)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint);
//不设置焦点策略点击按钮后会触发tableView的Tab键原因尚不清楚
ui->btnConfirm->setFocusPolicy(Qt::NoFocus);
ui->btnCancle->setFocusPolicy(Qt::NoFocus);
m_promptString = "";
m_patternString = "";
connect(ui->plainTextEdit, &QPlainTextEdit::textChanged, this, &TextEditWidget::onTextChanged);
connect(ui->btnConfirm, &QPushButton::clicked, this, &TextEditWidget::onBtnClicked_confirm);
connect(ui->btnCancle, &QPushButton::clicked, this, &TextEditWidget::onBtnClicked_cancle);
}
TextEditWidget::~TextEditWidget()
{
delete ui;
}
// bool TextEditWidget::eventFilter(QObject* obj, QEvent* event)
// {
// if (event->type() == QEvent::KeyPress)
// {
// QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(event);
// if (pKeyEvent->key() == Qt::Key_Tab)
// {
// qDebug() << "Key_Tab";
// return true;
// }
// }
// return QWidget::eventFilter(obj, event);
// }
QString TextEditWidget::editText()
{
return ui->plainTextEdit->toPlainText();
}
void TextEditWidget::setEditText(const QString& text)
{
ui->plainTextEdit->setPlainText(text);
}
void TextEditWidget::setPrompt(const QString& prompt)
{
m_promptString = prompt;
ui->label->setText(m_promptString);
}
void TextEditWidget::setRegularExpression(const QString& pattern)
{
//QPlainTextEidt没有setValidator方法所以需要在textChanged槽函数中进行处理
/*QRegularExpression regExp(pattern);
QRegularExpressionValidator* validator = new QRegularExpressionValidator(regExp, this);
ui->plainTextEdit->setValidator(validator);*/
m_patternString = pattern;
m_regExp.setPattern(m_patternString.replace(1, 0 , "^"));
}
void TextEditWidget::setErrorInfo(const QString& errorInfo)
{
ui->label->setText(errorInfo);
}
void TextEditWidget::onTextChanged()
{
ui->label->setText(m_promptString);
if(m_patternString.isEmpty())
return;
QString text = ui->plainTextEdit->toPlainText();
QString filtered = text;
filtered.replace(m_regExp, "");
//qDebug() << text << " " << m_regExp.pattern() << " " << filtered;
if (filtered != text)
{
// 保存光标位置,避免替换后光标跳转
QTextCursor cursor = ui->plainTextEdit->textCursor();
int pos = cursor.position();
ui->plainTextEdit->setPlainText(filtered);
cursor.setPosition(pos - (text.length() - filtered.length()));
ui->plainTextEdit->setTextCursor(cursor);
}
}
void TextEditWidget::onBtnClicked_confirm()
{
emit confirm();
}
void TextEditWidget::onBtnClicked_cancle()
{
emit cancle();
}
AttributeTableDelegate::AttributeTableDelegate(QTableView* view, const QString& connection, QObject *parent)
: QStyledItemDelegate(parent)
, m_tableView(view)
, m_connection(connection)
{
}
@ -22,7 +130,7 @@ void AttributeTableDelegate::paint(QPainter* painter, const QStyleOptionViewItem
}
//处理加粗字体逻辑
if(/*index.column() == 0 || */index.data(Qt::UserRole + 100).toBool())
if(/*index.column() == 0 || */index.data(Qt::UserRole + AttributeEidt::EditStatus).toBool())
{
opt.font.setBold(true);
//opt.palette.setColor(QPalette::Text, Qt::red);
@ -45,5 +153,130 @@ void AttributeTableDelegate::paint(QPainter* painter, const QStyleOptionViewItem
painter->restore();
}
}
}
QWidget* AttributeTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
{
int dataCol = index.column() - 1;
if(dataCol == 0) //属性类型
{
TextEditWidget* textEditor = new TextEditWidget(parent);
textEditor->setPrompt(QString::fromWCharArray(L"类型为英文"));
textEditor->setRegularExpression("[A-Za-z0-9]");
connect(textEditor, &TextEditWidget::confirm, this, [=]{
QString strText = textEditor->editText();
bool exists = SqlQueryExecutor::instance().attributeTypeExistsInDB(m_connection, strText);
if(exists)
textEditor->setErrorInfo(QString::fromWCharArray(L"该类型已存在"));
else
{
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
}
});
connect(textEditor, &TextEditWidget::cancle, this, [=]{
//createEditor为const成员函数而closeEditor是QAbstractItemDelegate的非const信号在const成员函数中不能直接调用需要转换为非const指针
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
return textEditor;
}
else if(dataCol == 1 || dataCol == 4) //1-数据名称、4-默认值
{
TextEditWidget* textEditor = new TextEditWidget(parent);
connect(textEditor, &TextEditWidget::confirm, this, [=]{
emit const_cast<AttributeTableDelegate*>(this)->commitData(textEditor);
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
connect(textEditor, &TextEditWidget::cancle, this, [=]{
emit const_cast<AttributeTableDelegate*>(this)->closeEditor(textEditor, QAbstractItemDelegate::NoHint);
});
return textEditor;
}
else if(dataCol == 2) //数据类型
{
if(m_tableView)
{
auto* model = qobject_cast<AttributeTableModel*>(m_tableView->model());
if(model)
{
QMap<int, AttributeTableModel::DataType> dataTypes = model->getDataTypes();
QComboBox* comboBox = new QComboBox(parent);
for(auto dataType : dataTypes)
comboBox->addItem(dataType.type);
return comboBox;
}
}
}
else if(dataCol == 3) //数据长度
{
QSpinBox* spinBox = new QSpinBox(parent);
spinBox->setRange(-1, 999);
spinBox->setValue(0);
return spinBox;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
// void AttributeTableDelegate::destroyEditor(QWidget* editor, const QModelIndex& index) const
// {
// emit const_cast<AttributeTableDelegate*>(this)->closeEditor(editor, QAbstractItemDelegate::NoHint);
// }
void AttributeTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
textEditor->setEditText(index.data(Qt::DisplayRole).toString());
else
QStyledItemDelegate::setEditorData(editor, index);
}
void AttributeTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QVariant newValue;
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
newValue = textEditor->editText();
else if(QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor))
newValue = lineEdit->text();
else if(QComboBox* comboBox = qobject_cast<QComboBox*>(editor))
newValue = comboBox->currentText();
else if(QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor))
newValue = spinBox->value();
else
{
QStyledItemDelegate::setModelData(editor, model, index);
return;
}
QVariant oldValue = index.data(Qt::EditRole);
//qDebug() << "newValue: " << newValue.toString() << "oldValue: " << oldValue.toString();
if (newValue == oldValue)
return;
model->setData(index, newValue, Qt::EditRole);
}
void AttributeTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(TextEditWidget* textEditor = qobject_cast<TextEditWidget*>(editor))
{
QSize editorSize = textEditor->size();
QRect optRect = option.rect;
QWidget* parentWidget = textEditor->parentWidget();
int nX = optRect.x();
if(parentWidget && (nX + editorSize.width()) > parentWidget->width())
nX = parentWidget->width() - editorSize.width();
int nY = optRect.bottom() - editorSize.height();
if(nY < 0)
nY = 0;
textEditor->setGeometry(nX, nY, editorSize.width(), editorSize.height());
}
else
editor->setGeometry(option.rect);
}
bool AttributeTableDelegate::isEnumType(const QModelIndex& index) const
{
return index.data(Qt::UserRole + AttributeEidt::DataType).toInt() == AttributeEidt::ENUM;
}

View File

@ -1,4 +1,5 @@
#include "attributeTableModel.h"
#include "attributeNamespace.h"
#include "logger.h"
#include "sqlQueryExecutor.h"
@ -12,7 +13,7 @@ AttributeTableModel::AttributeTableModel(const ModelAttributeGroup& modelAttribu
m_paginationInfo.currentPage = 1;
m_paginationInfo.totalEntries = 0;
getDataTypes();
getDataTypesFromDB();
iniDisplayField();
refresh();
}
@ -80,9 +81,20 @@ QVariant AttributeTableModel::data(const QModelIndex& index, int role) const
int dataCol = col - 1;
const RowData& rowData = m_currentPageData[row];
if (role == Qt::DisplayRole || role == Qt::EditRole)
//return rowData.record.value(dataCol);
return rowData.values.value(dataCol);
else if (role == Qt::UserRole + 100) //以100来标识数据是否被编辑,在相关代理Delegate类实现中同步进行处理文字加粗等效果
{
if(dataCol == 2) //数据类型存储的是id展示text
{
int dataTypeID = rowData.values.value(dataCol).toInt();
const QString& dataTypeText = m_dataTypes.value(dataTypeID).type;
if(!dataTypeText.isEmpty())
return dataTypeText;
else
return dataTypeID;
}
else
return rowData.values.value(dataCol);
}
else if (role == Qt::UserRole + AttributeEidt::EditStatus) //在相关代理Delegate类实现中同步进行处理文字加粗等效果
return (rowData.state != Clean);
}
@ -105,14 +117,21 @@ bool AttributeTableModel::setData(const QModelIndex &index, const QVariant &valu
int dataCol = index.column() - 1; //第一列显示了行号
//记录修改
RowData modifiedRow = m_currentPageData[row];
//modifiedRow.record.setValue(dataCol, value);
modifiedRow.values[dataCol] = value;
if(dataCol == 2) //数据类型
{
QString dataType = value.toString();
int id = getDataTypeID(dataType);
modifiedRow.values[dataCol] = id;
//qDebug() << "dataType-id: " << id;
}
else
modifiedRow.values[dataCol] = value;
modifiedRow.state = (modifiedRow.state == New) ? New : Modified;
m_modifiedRows[globalRow] = modifiedRow;
m_currentPageData[row] = modifiedRow;
emit dataChanged(index, index, {role, Qt::UserRole + 100});
emit dataChanged(index, index, {role, Qt::UserRole + AttributeEidt::EditStatus});
emit syncDataStatus(m_modifiedRows.isEmpty(), m_paginationInfo);
return true;
}
@ -173,7 +192,7 @@ void AttributeTableModel::iniDisplayField()
FieldInfo field3;
field3.originalName = "data_type_id";
field3.displayName = QString::fromWCharArray(L"数据类型");
//field3.dataType = "bigint";
field3.dataType = "character varying(64)";
m_displayField.append(field3);
FieldInfo field4;
@ -192,11 +211,13 @@ void AttributeTableModel::iniDisplayField()
for(int i = 0; i < m_displayField.count(); i++)
{
QString strFiled = m_displayField.at(i).originalName;
if(strFiled == "data_type_id") //数据类型以字符串的方式显示
continue;
m_displayField[i].dataType = fieldType.value(strFiled);
}
}
void AttributeTableModel::getDataTypes()
void AttributeTableModel::getDataTypesFromDB()
{
QString strSQL = "SELECT * FROM basic.data_type ORDER BY id ASC";
try
@ -209,6 +230,7 @@ void AttributeTableModel::getDataTypes()
dataType.type = query.value(1).toString();
dataType.db = query.value(2).toString();
m_dataTypes.insert(dataType.id, dataType);
m_reversalDataTypes.insert(dataType.type, dataType.id);
}
}
catch (const DatabaseException& e)
@ -217,6 +239,11 @@ void AttributeTableModel::getDataTypes()
}
}
int AttributeTableModel::getDataTypeID(const QString& type)
{
return m_reversalDataTypes.value(type, 11); //11是VARCHAR的id作为默认值
}
void AttributeTableModel::loadPageData()
{
m_currentPageData.clear();
@ -245,7 +272,7 @@ void AttributeTableModel::loadPageData()
{
Attribute attribute;
attribute.id = query.value(0).toInt();
if(SqlQueryExecutor::instance().getAtrributeInfo(m_connection, columns.join(", "), attribute))
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
{
RowData data;
data.values.append(attribute.type);

View File

@ -12,15 +12,14 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
, m_modelAttributeGroup(modelAttributeGroup)
{
m_tableView = new QTableView(this);
// m_tableView->setAlternatingRowColors(true);
// m_tableView->setStyleSheet("QTableView{alternate-background-color: rgb(240, 248, 255);}");
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->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
//m_tableView->setTabKeyNavigation(false); //关闭tab键导航
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
m_tableView->setModel(m_attributeTableModel);
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_tableView);
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_connection, m_tableView);
m_tableView->setItemDelegate(delegate);
//自定义表头
@ -41,7 +40,7 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
}
m_tableView->setHorizontalHeader(m_multiLinHeader);
//除了第一列其余列恢复可以手动调整模式
QTimer::singleShot(1000, [=](){
QTimer::singleShot(1000, this, [=](){
for(int i = 1; i < m_multiLinHeader->count(); i++)
m_multiLinHeader->setSectionResizeMode(i, QHeaderView::Interactive);
});

View File

@ -17,9 +17,13 @@ ConnectionDialog::ConnectionDialog(QWidget *parent)
{
//Linux下默认的Qt::Dialog即使有父窗口也无法按照子窗口的行为进行展示并且最大、最小按钮不好关闭因此需要去掉Dialog属性随之而来的问题是模态无法起作用
setWindowFlags(windowFlags() & ~Qt::Dialog);
setStyleSheet("QDialog{border: 1px solid rgb(205,205,205);border-radius:5px;}");
setStyleSheet("QDialog{border: 1px solid rgb(205,205,205);border-radius:5px;background-color:rgb(245,245,245);}");
}
setModal(true);
else
{
setModal(true);
}
initialize();
}

View File

@ -13,7 +13,7 @@ MessageDialog::MessageDialog(QWidget *parent)
{
//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);}");
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
{

View File

@ -446,7 +446,7 @@ int SqlQueryExecutor::getAttributeCount(const QString& connectionName, int model
return count;
}
bool SqlQueryExecutor::getAtrributeInfo(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);
try
@ -472,6 +472,23 @@ bool SqlQueryExecutor::getAtrributeInfo(const QString& connectionName, const QSt
return true;
}
bool SqlQueryExecutor::attributeTypeExistsInDB(const QString& connectionName, const QString& type)
{
bool exists = false;
QString strSQL = "SELECT id FROM basic.attribute WHERE attribute = \'" + type + "\'";
try
{
QSqlQuery query = executeSQL(connectionName, strSQL);
if(query.next())
exists = true;
}
catch (const DatabaseException& e)
{
exists = true;
}
return exists;
}
bool SqlQueryExecutor::batchInsertAttributes(const QString& connectionName, int modelID, int attributeGroupID, QList<Attribute> attributes)
{
//属于批量操作,需要开启事务

214
ui/textEditWidget.ui Normal file
View File

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TextEditWidget</class>
<widget class="QWidget" name="TextEditWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>204</width>
<height>94</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget #TextEditWidget
{
border: 1px solid rgb(205,205,205);
background-color:rgb(255,255,255);
}</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="contentWidget" native="true">
<property name="styleSheet">
<string notr="true">QWidget #contentWidget
{
border: 1px solid rgb(205,205,205);
background-color:rgb(255,255,255);
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<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>5</number>
</property>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::ClickFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">background-color: transparent;
border:0px;
padding:2px;</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="bottomWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QWidget #bottomWidget
{
background-color: transparent;
}</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);
font: 8pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>该类型已存在</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>5</number>
</property>
<item>
<widget class="QPushButton" name="btnCancle">
<property name="minimumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton
{
border: 1px solid rgb(205,205,205);
border-radius:5px;
}
QPushButton:hover
{
border-color: rgb(70,130,180);
}
QPushButton:pressed
{
background-color:rgba(70,130,180,50);
}</string>
</property>
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnConfirm">
<property name="minimumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton
{
color: rgb(250, 250, 250);
font: 10pt;
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>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>