سؤال

انا املك QTreeWidgetItem مع عمودين من البيانات ، هل هناك أي طريقة لجعل العمود الثاني فقط قابل للتحرير؟ عندما أفعل ما يلي:

QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);

جميع الأعمدة تصبح قابلة للتحرير.

هل كانت مفيدة؟

المحلول

يبدو أنك ستضطر إلى التخلي عن استخدام QTreeWidget و QTreeWidgetItem واذهب مع QTreeView و QAbstractItemModel. فصول "القطعة" هي فصول راحة هي تطبيقات ملموسة للإصدارات الأكثر تجريدًا ولكن أكثر مرونة. QAbstractItemModel لديه مكالمة flags(QModelIndex index) حيث ستقوم بإرجاع القيمة المناسبة لعمودك.

نصائح أخرى

يمكنك عمل أعمدة معينة فقط في qtreewidget قابلة للتحرير باستخدام حلول:

1) اضبط خاصية EditTriggers الخاصة بـ QtreewIdget على NoEditTriggers

2) عند إدراج العناصر ، قم بتعيين QT: العلم القابل للإلغاء لكائن QTREewIdgetItem

3) قم بتوصيل الفتحة التالية بإشارة "itemDoubleClected" لكائن qtreewidget:

void MainWindow::onTreeWidgetItemDoubleClicked(QTreeWidgetItem * item, int column)
{
    if (isEditable(column)) {
        ui.treeWidget->editItem(item, column);
    }
}

حيث "Isedable" هي وظيفة كتبتها تُرجع بشكل صحيح للأعمدة القابلة للتحرير والخطأ للأعمدة غير القابلة للتحرير.

واجهت نفس المشكلة مؤخرًا واكتشفت حلًا يعمل مع جميع EditTriggers ، وليس فقط الحجم المزدوج (والاتصال بإشارة النقر المزدوج)

إنشاء مندوب ، يعيد مؤشر فارغ للمحرر:

class NoEditDelegate: public QStyledItemDelegate {
    public:
      NoEditDelegate(QObject* parent=0): QStyledItemDelegate(parent) {}
      virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
        return 0;
      }
    };

وبعد ذلك استخدمه كمندوب مخصص لعمودك

ui->parameterView->setItemDelegateForColumn(0, new NoEditDelegate(this));

يبدو أن qtreewidget القياسي لا يسمح بذلك. أعتقد أن هناك طريقتان للقيام بذلك:

  1. استخدم QtreeView مع فئتك المستمدة من QabstractItemModel وتجاوز وظيفة الأعلام

  2. استخدم QtreeView مع QStandArdItemModel. ثم عند إضافة العنصر ، فقط قم بتعيين العمود المناسب للسماح بتحريرات:

إليك بعض التعليمات البرمجية للخيار الثاني:

QString x, y;
QList<QStandardItem*> newIt;
QStandardItem * item = new QStandardItem(x);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
newIt.append(item);
item = new QStandardItem(y);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable);
newIt.append(item);
model->appendRow(newIt);

أجد النهج الثاني أبسط ولكن هذا يعتمد على مقدار المرونة التي تريدها مع النموذج الخاص بك.

أبسط طريقة وجدتها هي استخدام QT :: itemflags

void myClass::treeDoubleClickSlot(QTreeWidgetItem *item, int column)
{
    Qt::ItemFlags tmp = item->flags();
    if (isEditable(item, column)) {
        item->setFlags(tmp | Qt::ItemIsEditable);
    } else if (tmp & Qt::ItemIsEditable) {
        item->setFlags(tmp ^ Qt::ItemIsEditable);
    }
}

الجزء العلوي من if يضيف وظيفة التحرير من خلال OR, والتحقق من أسفل ما إذا كان هناك AND, ، ثم يزيله مع XOR.

بهذه الطريقة تتم إضافة وظيفة التحرير عندما تريدها ، وإزالتها عندما لا تفعل ذلك.

ثم قم بتوصيل هذه الوظيفة بعناية الشجرة itemDoubleClicked() إشارة ، واكتب قرار "لتحرير أو عدم تحرير" بداخله isEditable()

class EditorDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    EditorDelegate(QObject *parent):QItemDelegate(parent){};
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

QWidget* EditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(index.column() == 1)
    {
        return QItemDelegate::createEditor(parent, option, index);
    }
    return nullptr;
}

في ال QTreeWidget:

myQTreeWidget::myQTreeWidget()
{
    EditorDelegate *d = new EditorDelegate(this);
    this->setItemDelegate(d);
}

ربما تأخرت قليلاً ، ولكن قد تساعد:

void MyClass::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) {
    Qt::ItemFlags flags = item->flags();
    if(column == 0)
    {
        item->setFlags(flags & (~Qt::ItemIsEditable));
    }
    else
    {
        item->setFlags(flags | Qt::ItemIsEditable);
    } 
}

هنا 0 هو فهرس العمود الذي تريد صنعه بقراءة.

flags & (~Qt::ItemIsEditable)

يحدد الموضع القابل للملاحة إلى 0 بغض النظر عن العلم السابق للعنصر الخاص بك.

flags | Qt::ItemIsEditable

يحددها على 1 بغض النظر عن العلم السابق.

أنا جديد على Pyside و Python بشكل عام ، لكنني تمكنت من الحصول على هذا العمل من خلال التسجيل مع QtreewIdget لعمليات الاسترجاعات التي تم تحديدها. ضمن رد الاتصال ، تحقق من العمود واتصل فقط بـ "EditItem" إذا كان ذلك لعمود تريد السماح بالتحرير.

class Foo(QtGui.QMainWindow):
...
def itemClicked(self, item, column):
   if column > 0:
      self.qtree.editItem(item, column)

من خلال عدم استدعاء EditItem للعمود 0 ، يتم التخلص من الحدث بشكل أساسي.

اكتشفت أن الكود أدناه يعمل بشكل جيد لاحتياجاتي ويقوم "كيندا" منع المستخدم من تحرير أجزاء معينة من الأعمدة:

أنا أتحقق بشكل أساسي من الدور ثم العمود. أسمح فقط بالتحرير في العمود 0. لذا إذا قام المستخدم بتحريره في أي عمود آخر ، فأنا أوقف تحرير setData ولم يتم إجراء أي تغيير.

void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
    if (role == Qt::ItemIsEditable && column != 0){
        return;
    }
    QTreeWidgetItem::setData(column, role, value);
}

قم بتعيين طفل عرض الأشجار القابل للتحرير أم لا (Itmes of Tree) ، استنادًا إلى الصف والعمود.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top