0

我基于 QTableView 创建自己的小部件。它类似于文件对话框(列表)。我想凭直觉行事。

a) 使用整行

b) 指标也适用于整行

c) 使用switched进入下层(子目录)

d) 运行程序后或移动到较低级别的光标必须在表的第一行(第 0 行)

而且有问题。我不能强制程序将光标放在第一行。我尝试了几种方法,但都没有成功。设置当前索引。selectRow 等。光标总是在其他地方。没有突出显示,不是在第一行,但是一旦它在 10 位置上,第二在 4 位置等上。它的行为不可预测。

我该怎么做?

这里我的代码是:

mFileBoxWidget::mFileBoxWidget(QWidget *parent) :
    QTableView(parent)
    ,model(new QFileSystemModel())
{
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setShowGrid(false);
    this->verticalHeader()->setVisible(false);
    this->installEventFilter(this);
    model->setReadOnly(true);
    this->setModel(model);
    this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch ); 
    this->setColumnWidth(1,70);
    this->setColumnWidth(2,70);
    this->setColumnWidth(3,110);
    this->setRootIndex(model->setRootPath("C://"));
    this->setSelectionMode(QAbstractItemView::SingleSelection);
    this->setSelectionBehavior(QAbstractItemView::SelectRows);
    //this->selectRow(0); //Does not work - goto first row
    //this->setCurrentIndes(Index); //Does not work - goto index x=0 y=0
}

预先感谢您的所有回复。

4

3 回答 3

2

Solved! The problem is that the model is asynchronous. So reads the data in another thread. When I tried to set the index to the first line, still basically did not exist. The solution is, of course, to wait for loading the thread. At this point signal directoryLoaded(QString) is send. As a result, it is necessary to wait for the signal, and only then set index.

connect(myModel, SIGNAL(directoryLoaded(QString)), this, SLOT(onLoaded()));

void mFileBoxWidget::onLoaded()
{

    QModelIndex index = myModel->index(myModel->rootPath());

    this->setCurrentIndex(index.child(0, index.column()));
}
于 2013-06-27T09:22:43.613 回答
0

你不应该命名你的成员变量model。QTableView 有函数 model(),编译器认为 this->model 应该是 this->model(),因此你得到你提到的错误。

于 2013-06-13T18:51:53.653 回答
0

这是未经测试的代码,但我认为这样的事情应该可以工作:

QModelIndex firstRow = QTableView::model()->index(0, 0);
QTableView::selectionModel()->select(firstRow,
                               QItemSelectionModel::ClearAndSelect |
                               QItemSelectionModel::Rows );

编辑:(2013-06-19 06:12:58 UTC)

到目前为止对我有用的一个简单(且丑陋)的解决方法是触发对m_tableView->selectRow(0); 从一个QTimer

这是示例代码:

标题:

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>

class QTableView;
class QFileSystemModel;

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();

private:

    void layoutWidgets();

    QFileSystemModel *m_model;
    QTableView *m_tableView;

private slots:

    void selectFirstRow();

    // for debugging only
    void selectionChanged();
};

#endif // MAINWIDGET_H

执行:

#include "mainwidget.h"
#include <QTableView>
#include <QHBoxLayout>
#include <QFileSystemModel>
#include <QHeaderView>
#include <QTimer>

MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{

    m_tableView = new QTableView(this);
    m_model = new QFileSystemModel(this);
    m_model->setReadOnly(true);

    m_tableView->setModel(m_model);

    m_tableView->setRootIndex(m_model->setRootPath(QDir::homePath()));
    m_tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_tableView->setShowGrid(false);
    m_tableView->verticalHeader()->setVisible(false);
    m_tableView->setColumnWidth(1,70);
    m_tableView->setColumnWidth(2,70);
    m_tableView-> setColumnWidth(3,110);
    m_tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    //m_tableView->->setSectionResizeMode(0, QHeaderView::Stretch );  // Qt 5?

    layoutWidgets();

    connect(m_tableView->selectionModel(),     SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged()) );

    // This works
    QTimer::singleShot(1000, this, SLOT(selectFirstRow()));

    // Direct invocation - doesn't works
    // selectFirstRow();
}

void MainWidget::layoutWidgets()
{
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(m_tableView);
    setLayout(mainLayout);
    setFixedSize(500,500);
}

void MainWidget::selectFirstRow()
{    
    m_tableView->selectRow(0);
}

void MainWidget::selectionChanged()
{
   qDebug("Selection changed");
}

MainWidget::~MainWidget()
{}

奇怪的是,如果QTimer::singleShot()需要至少延迟约 25 毫秒来触发。,否则它将无法在我的系统中运行。

这是替代方案,子类化QTableView

#include "mytableview.h"
#include <QFileSystemModel>
#include <QHeaderView>
#include <QTimer>


MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{

    QFileSystemModel *myModel = new QFileSystemModel;

    setModel(myModel);
    setRootIndex(myModel->setRootPath(QDir::homePath()));


    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setShowGrid(false);
    verticalHeader()->setVisible(false);
    //installEventFilter(this);
    myModel->setReadOnly(true);

    //setSectionResizeMode(0, QHeaderView::Stretch );  // Qt 5

    setColumnWidth(1,70);
    setColumnWidth(2,70);
    setColumnWidth(3,110);

    setSelectionMode(QAbstractItemView::SingleSelection);
    setSelectionBehavior(QAbstractItemView::SelectRows);



    QTimer::singleShot(100, this, SLOT(selectFirstRow()));

    connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged()));

}

void MyTableView::selectFirstRow()
{
//    qDebug("Selecting first row");
//    QModelIndex firstRow = QTableView::model()->index(0,0);

//    if(firstRow.isValid()){

//        selectionModel()->select(firstRow, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows  );
//    }else{
//        qDebug("Invalid index");
//    }

    selectRow(0);
}

void MyTableView::selectionChanged()
{
    qDebug("Selection changed.");
}
于 2013-06-12T05:08:19.287 回答