web-dev-qa-db-ja.com

QTreeWidgetItemの1列のみを編集可能にする

2列のデータを含むQTreeWidgetItemがありますが、2番目の列のみを編集可能にする方法はありますか?私が次のことをすると:

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

すべての列が編集可能になります。

26
Andreas Brinck

QTreeWidgetQTreeWidgetItemの使用を忘れて、QTreeViewQAbstractItemModelを使用する必要があるようです。 「ウィジェット」クラスは、より抽象的でより柔軟なバージョンの具体的な実装である便利なクラスです。 QAbstractItemModelにはflags(QModelIndex index)の呼び出しがあり、列に適切な値を返します。

7

回避策を使用して、QTreeWidgetの特定の列のみを編集可能にすることができます。

1)QTreeWidgetのeditTriggersプロパティをNoEditTriggersに設定します

2)アイテムの挿入時に、QTreeWidgetItemオブジェクトのQt:ItemIsEditableフラグを設定します

3)次のスロットをQTreeWidgetオブジェクトの「itemDoubleClicked」信号に接続します。

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

ここで、「isEditable」は、編集可能な列の場合はtrueを返し、編集できない列の場合はfalseを返すように記述した関数です。

27
d11

私は最近同じ問題を抱えており、DoubleClickedだけでなく(およびダブルクリックされた信号への接続も)すべてのEditTriggersで機能する解決策を発見しました

エディターにNULLポインターを返すデリゲートを作成します。

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));
19
user571167

標準のQTreeWidgetではこれが許可されていないようです。これには2つの方法があると思います。

  1. QAbstractItemModelから派生した独自のクラスでQTreeViewを使用し、フラグ関数をオーバーライドします

  2. QTreeItemViewでQTreeViewを使用します。次に、アイテムを追加するときに、適切な列を設定して編集を許可します。

2番目のオプションのコードは次のとおりです。

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);

2番目のアプローチの方が簡単だと思いますが、それはモデルにどの程度の柔軟性が必要かによって異なります。

8
Blaise

私が見つけた最も簡単な方法は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()内に「編集するか編集しないか」の決定を記述します

6
clark
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);
}
3
user336063

多分少し遅れますが、役立つかもしれません:

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)

アイテムの前のフラグに関係なく、ItemIsEditableの位置を0に設定します。

flags | Qt::ItemIsEditable

前のフラグに関係なく、1に設定します。

2
chraz

以下のコードは私のニーズにうまく機能し、ユーザーが列の特定の部分を編集するのを「やや」停止することがわかりました。

基本的に役割をチェックしてから、列を確認します。私は列0での編集のみを許可します。したがって、ユーザーが他の列でそれを編集する場合、setData編集を停止し、変更は行われません。

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

私はPySideとPythonを一般的に使用していますが、itemClickedコールバックのQTreeWidgetに登録することでこれを機能させることができました。コールバック内で列を確認し、 'editItem '編集を許可する列の場合。

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

列0のeditItemを呼び出さないことにより、イベントは基本的に破棄されます。

1
Kerry

行と列に基づいて、ツリーウィジェットの子を編集可能かどうか(ツリーの要素)に設定します。

0
Naruto