3

QTableWidget で (Microsoft Excel で利用可能な) フィルター メカニズムを作成するアイデアを誰か教えてもらえますか?

列名をクリックするたびに、ヘッダー フィルター メカニズムがそのテーブルに対して自動的にアクティブになるようにします。

私はWindows上で構築しています。


更新これは私が持っている部分的な実装です。testanother(const QString &text)しかし、一致するデータをテーブルに表示し、一致しないデータを非表示にするスロットの実装について助けが必要です。

bool TableData::filterSlot() {
    int columnCount = this->tablewidget->columnCount();
    int rowCount = this->tablewidget->rowCount();
    QStringList filterList;
    QString temp_string;
    qDebug()<<"Count inside filter slot is";
    qDebug()<<rowCount<<":"<<columnCount;
    for(int c = 0; c<columnCount;c++) {
        for(int r = 0; r<rowCount;r++) {
            temp_string = this->tablewidget->item(r,c)->text(); 
            if(!filterList.contains(temp_string))
                filterList << temp_string;
        }
        filterList << "None";
        combo = new QComboBox(tablewidget);
        combo->addItems(filterList);
        combo->setCurrentIndex(filterList.count()-1);
        this->tablewidget->setCellWidget(0,c,combo);
        filterList.clear();
        connect(combo,SIGNAL(activated(const QString &)),
            this,SLOT(testAnother(const QString &)));
    }
    return true;
}

void TableData::testAnother(const QString &text) {
    int c = sender()->objectName().toInt();
}
4

2 に答える 2

3

から継承する列トラッキング レイアウトを作成しましたQHBoxLayout。ウィジェットをヘッダーに埋め込むほどではありませんが、少なくとも、ウィジェットがそれぞれのテーブル列にバインドされているように見えます。

デモのスクリーンキャプチャ

ここに画像の説明を入力

このプロジェクトは、 https://github.com/sashoalm/ColumnAlignedLayoutの GitHub でホストされています。

columnalignedlayout.cpp と columnalignedlayout.h だけが必要です

小さいので直接貼り付けます。

columnalignedlayout.h

#ifndef COLUMNALIGNEDLAYOUT_H
#define COLUMNALIGNEDLAYOUT_H

#include <QHBoxLayout>

class QHeaderView;

class ColumnAlignedLayout : public QHBoxLayout
{
    Q_OBJECT
public:
    ColumnAlignedLayout();
    explicit ColumnAlignedLayout(QWidget *parent);
    void setTableColumnsToTrack(QHeaderView *view) { headerView = view; }

signals:

public slots:

private:
    void setGeometry(const QRect &r);
    QHeaderView *headerView;
};

#endif // COLUMNALIGNEDLAYOUT_H

columnalignedlayout.cpp

#include "columnalignedlayout.h"
#include <QHeaderView>

ColumnAlignedLayout::ColumnAlignedLayout()
    : QHBoxLayout()
{

}

ColumnAlignedLayout::ColumnAlignedLayout(QWidget *parent)
    : QHBoxLayout(parent)
{

}

void ColumnAlignedLayout::setGeometry(const QRect &r)
{
    QHBoxLayout::setGeometry(r);

    Q_ASSERT_X(headerView, "layout", "no table columns to track");
    if (!headerView) {
        return;
    }

    Q_ASSERT_X(headerView->count() == count(), "layout", "there must be as many items in the layout as there are columns in the table");
    if (headerView->count() != count()) {
        return;
    }

    Q_ASSERT(parentWidget());

    int widgetX = parentWidget()->mapToGlobal(QPoint(0, 0)).x();
    int headerX = headerView->mapToGlobal(QPoint(0, 0)).x();
    int delta = headerX - widgetX;

    for (int ii = 0; ii < headerView->count(); ++ii) {
        int pos = headerView->sectionViewportPosition(ii);
        int size = headerView->sectionSize(ii);

        auto item = itemAt(ii);
        auto r = item->geometry();
        r.setLeft(pos + delta);
        r.setWidth(size);
        item->setGeometry(r);
    }
}

使用例:

alignedLayout = new ColumnAlignedLayout();
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
ui->widget->setLayout(alignedLayout);
alignedLayout->setTableColumnsToTrack(ui->tableWidget->horizontalHeader());
alignedLayout->setParent(ui->widget);
connect(ui->tableWidget->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), SLOT(invalidateAlignedLayout()));
connect(ui->tableWidget->horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(invalidateAlignedLayout()));

そして、スロット呼び出しinvalidate():

void MainWindow::invalidateAlignedLayout()
{
    alignedLayout->invalidate();
}
于 2016-09-11T10:57:37.440 に答える
1

その特定の機能を実行する組み込みのものはありません。しかし、この人が行ったことのように、QHeaderView から独自のクラスを派生させることができます。

http://lists.qt.nokia.com/pipermail/qt-interest/2009-August/011654.html

試してみたところ、ウィジェット (テキスト ボックスとコンボ ボックス) を適切なヘッダー列の下に配置することに成功したようです。この手法を使用すると、長いテーブルとスクロールがある場合、フィルターはヘッダーに残ります。

(「偽の」行をプロキシ データ モデルに入れることを人々が提案する前のスレッドがありました。これは非常に恐ろしい方法であり、データを下にスクロールすると、フィルター列も上にスクロールしてしまいます。)

彼のサンプル コードは、フィルタリングを示していません。ただし、基本的な並べ替え/フィルタリング モデルの例を見ると、その機能のパターンを確認できます。

http://doc.qt.nokia.com/latest/itemviews-basicsortfiltermodel.html

良いニュースは、Qt がこのようなことを処理できるほど柔軟であることです。悪い (?) ニュースは、列ヘッダーに配置したウィジェットをどのように設定するかはあなた次第だということです。一意の値を見つけてコンボ ボックスに表示するためのスキャンは、作成しない限り行われません。ただし、固定リストを入力するのは簡単です。

于 2011-12-05T16:39:26.247 に答える