3

QTreeWidgetトラック名などを表示するために使用しているカスタムサブクラスがあります。私の MIDI エディター プロジェクト ( https://github.com/waddlesplash/ragingmidi ) で。このツリー ウィジェットに別の列を追加したいのですが、1 つのウィジェットがアイテムごとのウィジェットではなく、列全体を占めています。

これは可能ですか、それとも他の解決策を考え出す必要がありますか?

編集: 私はこのような何かを達成しようとしています: http://www.anvilstudio.com/compose.jpg - すべての行を示すヘッダー ビュー (「L/R バランス」の後の 3 番目) の最後の「列」を参照してください。 /notes (これは完全にカスタムであり、とにかく VB.NET とクローズド ソースで記述されています)。

編集 2 : 表示されませんが、上の図では他の列がスクロールせずに最後の列がスクロールします。彼らの方法では、マウスを使用してスクロールする必要があります。スクロールバーが欲しい。

4

3 に答える 3

2

Qt のドキュメントを見ると、これを実現するためのオプションがいくつかあるようですが、ニーズに最適なアプローチを決定する前に対処すべき重要な要素がいくつかあります。

  1. このカスタム ツリー列に表示されているコンテンツは静的ですか、それとも動的ですか?
  2. QTreeWidget からカスタム ツリー列への行の 1 対 1 マッピングはありますか?

カスタム ツリー列のコンテンツが静的で、行の 1 対 1 のマッピングがある場合は、QTreeWidget::setItemWidget ( QTreeWidgetItem * item, int column, QWidget * widget )関数を使用するだけで十分です。

ただし、カスタム ツリー列のコンテンツが動的であるか、行の 1 対 1 マッピングがない場合は、より複雑なアプローチが必要になります。

QTreeWidget のドキュメントに記載されているとおり。"カスタム動的コンテンツを表示したり、カスタム エディター ウィジェットを実装したい場合は、QTreeView とサブクラス QItemDelegate を使用してください。"

QItemDelegate とそのサブクラスは、Qt アイテム ビュー (QTreeView、QListView、QTableView など) に挿入されたアイテムのすべての描画機能を実行します。これにより、基本的に、QTreeView クラスに挿入されたアイテムのすべての描画操作を制御できるようになり、コンテンツを複数の行に拡張できることに加えて、動的コンテンツを描画できます。

QListWidget に同様のアプローチを実装したので、QItemDelegateの代わりにQStyledItemDelegateを使用することをお勧めします。これにより、このウィジェットをアプリケーションのスタイル レイアウトにより簡単に統合できるからです。このカスタム QWidget の正確な使用方法について詳しく説明しなかったため、QItemEditorCreatorQItemEditorCreatorBase、およびQItemEditorFactoryによって提供される追加機能も必要になる場合があります。可能であれば、私が開発した同様のウィジェットをここに投稿しますが、残念ながら、それは独自のソフトウェア スイートの一部です。

于 2013-03-15T18:35:08.263 に答える
0

カスタム ウィジェットが一番右の列にあり、列が狭くされている場合に問題が発生するため、これは完全にきれいではありませんが、最初は次のようになります。

#include <QtGui>

class TreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    TreeWidget();

    QRect columnRect(int column) const;

private slots:
    void repositionColumnWidget();

private:
    QPushButton * mColumnWidget;
};

TreeWidget::TreeWidget()
    : mColumnWidget(new QPushButton("Custom Column Button", viewport()))
{
    const int COLUMN_COUNT = 6;
    setColumnCount(COLUMN_COUNT);
    for (int row = 0; row < 400; ++row)
    {
        QStringList columns;
        for (int column = 0; column < COLUMN_COUNT; ++column)
        {
            columns << QString("row %1, column %2").arg(row + 1).arg(column + 1);
        }
        addTopLevelItem(new QTreeWidgetItem(columns));
    }
    for (int column = 0; column < COLUMN_COUNT; ++column)
    {
        resizeColumnToContents(column);
    }
    repositionColumnWidget();
    mColumnWidget->show();
    connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(repositionColumnWidget()));
    connect(header(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(repositionColumnWidget()));
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
    connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
}

QRect TreeWidget::columnRect(int column) const
{
    int itemCount = topLevelItemCount();
    if (!itemCount)
    {
        return QRect();
    }
    int columnX = header()->sectionViewportPosition(column);
    int columnY = visualItemRect(topLevelItem(0)).top();
    int columnWidth = header()->sectionSize(column);
    int columnHeight = visualItemRect(topLevelItem(itemCount-1)).bottom() - columnY + 1;

    return QRect(columnX, columnY, columnWidth, columnHeight);
}

void TreeWidget::repositionColumnWidget()
{
    mColumnWidget->setGeometry(columnRect(3));
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setQuitOnLastWindowClosed(true);

    TreeWidget treeWidget;

    treeWidget.resize(800, 600);
    treeWidget.show();

    return a.exec();
}

#include "main.moc"
于 2013-03-15T20:34:33.690 に答える
0

1 週間後、私の頭に浮かんだのは、H スクロールバーをハイジャックして、QTreeWidgetそのスクロールバーに最後の列だけをスクロールさせることです。現時点では、ウィンドウが 620x670 ピクセルの場合にすべての列が収まります。

これが悪い考えである理由について、より良い解決策や異議を唱える人がいない限り、これが私がやろうとしている方法です.

于 2013-03-18T20:47:10.073 に答える