博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
qt扩展属性框qtpropertybrowser 中添加按钮
阅读量:2433 次
发布时间:2019-05-10

本文共 10165 字,大约阅读时间需要 33 分钟。

simple

QtPropertyBrowser提供了丰富的示例来展示该扩展是如何使用的。

示例simple展示如下:

示例

其中包括int、bool、string等普通数据类型,file文件类型,group族类型等。如果要重绘某种类型的控件如何办呢?

特殊需求

比如在group中来增加两个按钮,实现组内成员的增减,效果如下:

示例
点击“+”,组内增加指定类型的成员,点击“-”,组内删除选中的成员。

问题

需要解决以下问题:

  1. 把按钮加进去
  2. 给多组“+”/"-"按钮绑定信号槽
  3. 改变group组的显示风格,例如:按钮正常状态下也要显示/不设置焦点捕获等
  4. 兼容int/double/bool/file等众多类型,模板化

方法

选用simple示例中展示的size类型来进行重写,当然你可以选择你感兴趣的任何类型。

QtVectorPropertyManager的实现

继承QtVariantPropertyManager,实现以下接口:

QString valueText(const QtProperty *property) const;	virtual void initializeProperty(QtProperty *property);	virtual void uninitializeProperty(QtProperty *property);	QtProperty *addProperty(const QString &name);

QtVectorEditoryFactory的实现

继承QtAbstractEditorFactory,实现以下接口:

void connectPropertyManager(QtArrayPropertyManager *manager);	QWidget *createEditor(QtArrayPropertyManager *manager, QtProperty *property,		QWidget *parent); //关于按钮的,主要在createEditor这个函数里实现。	void disconnectPropertyManager(QtArrayPropertyManager *manager);	void pushGroupItem(QtProperty *property);	void delGroupItem(QtProperty* property);	void btnSignalsSlots();

qtvectorypropertymanager.h

QtVectorPropertyManager.h

class  QtVectorPropertyManager: public QtVariantPropertyManager{
Q_OBJECTpublic: explicit QtVectorPropertyManager(QWidget *parent = 0); virtual ~QtVectorPropertyManager();public: // must a name to identity different group QtProperty *addProperty(const QString &name);// void setValue(const QString &value); void setTreeBrowser(QtAbstractPropertyBrowser* browser); QtAbstractPropertyBrowser* getTreeBrowser();protected: QString displayText(const QtProperty *property) const; QString valueText(const QtProperty *property) const; virtual void initializeProperty(QtProperty *property); virtual void uninitializeProperty(QtProperty *property);private: QMap
_propertyToGroup; // 用于动态绑定 QtAbstractPropertyBrowser *_browser;};

qtvectorypropertymanager.cpp

QtVectoryPropertyManager.cpp

QtVectoryPropertyManager::QtVectoryPropertyManager(QWidget *parent) :	QtVectoryPropertyManager(parent){
}QtVectoryPropertyManager::~QtVectoryPropertyManager(){
}// must a name to identity different groupQtProperty* QtVectoryPropertyManager::addProperty(const QString &name){
// add a top item QtProperty* topItem = QtVariantPropertyManager::addProperty(QVariant::Size, name); _propertyToGroup[topItem] = name; topItem->setGroupBox(true); return topItem;}//void QtVectoryPropertyManager::setValue(const QString &value){
return;}void QtVectoryPropertyManager::setTreeBrowser(QtAbstractPropertyBrowser* browser){
_browser = browser;}QtVectoryPropertyManager* QtArrayPropertyManager::getTreeBrowser(){
return _browser;}QString QtVectoryPropertyManager::displayText(const QtProperty *property) const{
return "";}QString QtVectoryPropertyManager::valueText(const QtProperty *property) const{
// nothing return; //QString text = QtVariantPropertyManager::valueText(property); //if (!_propertyToGroup.contains(property)) // return text; //QString data = _propertyToGroup[property]; return "";}void QtVectoryPropertyManager::initializeProperty(QtProperty *property){
return;}void QtVectoryPropertyManager::uninitializeProperty(QtProperty *property){
QtVariantPropertyManager::uninitializeProperty(property);}

qtvectoreditorfactory.h

使用模板,确保多类型的兼容。由于用了模板,类的实现也必须在头文件里完成。

template 
class QtVectorEditorFactory : public QtAbstractEditorFactory
{
public: explicit QtVectorEditorFactory(QObject *parent = 0); virtual ~QtVectorEditorFactory(); PropertyManager* subManager(); EditorFactory* subFactory();protected: void connectPropertyManager(QtVectoryPropertyManager*manager); QWidget *createEditor(QtVectoryPropertyManager*manager, QtProperty *property, QWidget *parent); void disconnectPropertyManager(QtVectoryPropertyManager *manager); void pushGroupItem(QtProperty *property); void delGroupItem(QtProperty* property); void btnSignalsSlots(); private: struct UserEditor {
QPushButton* btnAdd = nullptr; QPushButton* btnRemove = nullptr; bool isConnected = false; }; QtVariantEditorFactory *_originalFactory = nullptr; PropertyManager* _manager = nullptr; EditorFactory *_factory = nullptr; QMap
_porpertyToEditor; //different group,different index. // auto add index. QMap
_propertyIndex; };template
QtVectorEditorFactory< PropertyManager, EditorFactory >::QtArrayEditorFactory(QObject *parent) : QtAbstractEditorFactory
(parent){ _originalFactory = new QtVariantEditorFactory(this); _manager = new PropertyManager(this); _factory = new EditorFactory(this);}template
QtVectorEditorFactory< PropertyManager, EditorFactory >::~QtArrayEditorFactory(){ // not need to delete editor widgets, because they will be deleted by originalFactory in its destructor}template
PropertyManager* QtVectorEditorFactory< PropertyManager, EditorFactory >::subManager(){ return _manager;}template
EditorFactory* QtVectorEditorFactory< PropertyManager, EditorFactory >::subFactory(){ return _factory;}template
void QtVectorEditorFactory< PropertyManager, EditorFactory >::connectPropertyManager(QtVectoryPropertyManager *manager){ _originalFactory->addPropertyManager(manager); // set factory for tpl. manager->getTreeBrowser()->setFactoryForManager(_manager, _factory);}template
void QtVectorEditorFactory< PropertyManager, EditorFactory >::prepareSignalsSlots(){ QMap
::Iterator it = _porpertyToEditor.begin(); while (it != _porpertyToEditor.end()) { QtProperty* prop = it.key(); UserEditor ueditor = it.value(); if (!ueditor.isConnected) { // add button click singal and slot; connect(ueditor.btnAdd, &QPushButton::clicked, this, [=] { _propertyIndex[prop]++; this->pushBackGroupItem(prop); }); // del button clicked singal and slot; connect(ueditor.btnRemove, &QPushButton::clicked, this, [=] { this->removeGroupItem(prop); }); ueditor.isConnected = true; _porpertyToEditor[prop] = ueditor; } it++; }}template
QWidget *QtVectorEditorFactory< PropertyManager, EditorFactory >::createEditor(QtVectoryPropertyManager*manager, QtProperty *property, QWidget *parent){ // 这里指定了widget的parent,无需delete ... ???? QWidget* groupEditor = new QWidget(); QPushButton* btnAdd = new QPushButton(groupEditor); QPushButton* btnRemove = new QPushButton(groupEditor); UserEditor editor{ btnAdd,btnRemove,false }; _porpertyToEditor[property] = editor; groupEditor->setParent(parent); groupEditor->setToolTip("manager your properties here"); QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); QHBoxLayout *layout = new QHBoxLayout(groupEditor); groupEditor->setAttribute(Qt::WA_StyledBackground, true); groupEditor->setLayout(layout); layout->addItem(spacer); layout->setContentsMargins(0, 0, 0, 0); btnAdd->setFixedWidth(24); btnAdd->setToolTip("add"); btnRemove->setFixedWidth(24); btnRemove->setToolTip("remove"); btnAdd->setIcon(QIcon(":/res/add.svg")); btnRemove->setIcon(QIcon(":/res/remove.svg")); layout->addWidget(btnAdd); layout->addWidget(btnRemove); // bind signals and slots. // prepare signals and slots. btnSignalsSlots(); return groupEditor;}template
void QtVectorEditorFactory< PropertyManager, EditorFactory >::disconnectPropertyManager(QtVectoryPropertyManager*manager){ _originalFactory->removePropertyManager(manager); _originalFactory->addPropertyManager(manager);}template
void QtVectorEditorFactory< PropertyManager, EditorFactory >::pushGroupItem(QtProperty *property){ QtArrayPropertyManager *manager = propertyManager(property); if (!manager) return; QtProperty* itemTop = property; QList
properies = itemTop->subProperties(); QtProperty* item = _manager->addProperty(QString::number(_propertyIndex[property])); properies.append(item); itemTop->addSubProperty(item);}template
void QtVectorEditorFactory< PropertyManager, EditorFactory >::delGroupItem(QtProperty* property){ QtVectoryPropertyManager*manager = propertyManager(property); if (!manager) return; QtProperty* itemTop = property; QList
subProperties = itemTop->subProperties(); QtBrowserItem * curItem = manager->getTreeBrowser()->currentItem(); // select nothing. if (curItem == nullptr) return; QtProperty* curSelProperty = curItem->property(); // select top item. if (curSelProperty == itemTop) return; // remove selected from subproperties; for (int i = 0; i < subProperties.size(); i++) { if (subProperties.contains(curSelProperty)) { int ret = QMessageBox::warning(NULL, "warning", "Are you sure to remove?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (ret == QMessageBox::Yes) { //... // remove from list. itemTop->removeSubProperty(curSelProperty); return; } return; } }}

使用方法,以文件的类型为例:

// 创建一个array	_arrayManager = new QtVectorPropertyManager(this);		_arrayFactory = new QtVectorEditorFactory
(this); _arrayManager->setTreeBrowser(_brower); _brower->setFactoryForManager(_arrayManager, _arrayFactory); connect(_arrayFactory->subManager(), &QtFilePathPropertyManager::valueChanged, _arrayFactory->subFactory(), [=](QtProperty *subprop, const QString& val){
// do something ... });

改变group组的显示风格

例如:按钮正常状态下也要显示/不设置焦点捕获等

这个group组,正常状态下是需要显示“+”,“-”的,并不是每次点击属性都需要运行createEditor这个函数。这里就需要改qtpropertybrowser的源码了。

修改文件qttreepropertybrowser.cpp 函数propertyInserted

void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex){
QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex); QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent()); QTreeWidgetItem *newItem = 0; if (parentItem) {
newItem = new QTreeWidgetItem(parentItem, afterItem); } else {
newItem = new QTreeWidgetItem(m_treeWidget, afterItem); } m_itemToIndex[newItem] = index; m_indexToItem[index] = newItem; newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); if ( index->property()->isGroupBox() ) // index->property()->isGroupBox() 是个属性控制,区分正常显示与组框显示的风格。自己添加。。。 {
QWidget* editor = createEditor(index->property(), m_treeWidget); editor->setFocusPolicy(Qt::NoFocus); m_treeWidget->setItemWidget(newItem, 1, editor); } m_treeWidget->setItemExpanded(newItem, true); updateItem(newItem);}

在这里插入图片描述

在这里插入图片描述

至此,基本功能大概完成。很草率,写的代码自己都看不下去,只是提供个思路而已,抛转引玉…哎…

转载地址:http://dmvmb.baihongyu.com/

你可能感兴趣的文章
回复旦
查看>>
二十世纪计算机十大著名算法
查看>>
MFC程序更换XP皮肤
查看>>
SkinSharp使用方法
查看>>
盘点2010年电子书市场
查看>>
How Computers Know What We Want — Before We Do
查看>>
About Recommender Systems
查看>>
jason数据格式
查看>>
金山快盘的安全性太差了
查看>>
KDD Cup2011
查看>>
“相关性”时代的到来
查看>>
腾讯盛大百度版咆哮体
查看>>
opencv阈值法分割图像
查看>>
OpenCV资料
查看>>
常见域名后缀词典
查看>>
python编辑器对比和推荐
查看>>
极阅和微精
查看>>
回顾我的2011
查看>>
解析UTF8字符串,并截取每个字符到vector(C++代码)
查看>>
Outbrain
查看>>