Russian Qt Forum

Qt => Model-View (MV) => Тема начата: nickla от Апрель 24, 2012, 22:37



Название: QCompleter и QAbstractTableModel не работают.
Отправлено: nickla от Апрель 24, 2012, 22:37
Хочу чтобы у QComboBox была подсказка QCompleter с моделью QAbstractTableModel. Для этого делаю так в конструкторе диалога:

Код:
    QCompleter *completer = new QCompleter(this);
    m_ModelDriverAutocomplete = new ModelUserDriverAutocomplete(completer);
    completer->setModel(m_ModelDriverAutocomplete);
    completer->setWidget(ui->comboDriver);
    completer->setCompletionMode(QCompleter::PopupCompletion);
    completer->setCaseSensitivity(Qt::CaseInsensitive);
    completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
    ui->comboDriver->setCompleter(completer);

Класс модели наследуемой от QAbstractTableModel:

Код:
ModelUserDriverAutocomplete::ModelUserDriverAutocomplete(QObject *parent) :
    ModelAbstract(parent)
{
}

int ModelUserDriverAutocomplete::rowCount(const QModelIndex &parent) const
{
    return 2;
}

int ModelUserDriverAutocomplete::columnCount(const QModelIndex &parent) const
{
    return 1;
}

QVariant ModelUserDriverAutocomplete::data(const QModelIndex &index, int role) const
{
    qDebug() << "data" << index << role << index.row();
    if (index.row() == 0) {
        return QString("abc");
    } else if (index.row() == 1){
        return QString("acd");
    }
    return QVariant();
}

Открываю форму. В combobox ввожу "a". Появляется маленькая полосочка под combobox высотой в 3-4 пикселя. Главное эта полоска реагирует на ESC или на ALT+F4, но никаких надписей от QCompleter нет. Помогите пожалуйсто, почему не работает с QAbstractTableModel

PS: Если ввожу правильно, скажем "ab" то полоска есть. Но стоит ошибиться, скажем "abp" то она исчезает. ПО ощущениям это и есть QCompleter, только он высотой в 4 пикселя почемуто.


Название: Re: QCompleter и QAbstractTableModel не работают.
Отправлено: nickla от Апрель 24, 2012, 22:42
Изменил стиль QCompleter:

Код:
completer->setCaseSensitivity(Qt::CaseInsensitive);

И о чудо! Он правильно подсказывает. Почему тогда он так ущербно себя ведет если я хочу popup?


Название: Re: QCompleter и QAbstractTableModel не работают.
Отправлено: nickla от Апрель 24, 2012, 23:13
Решено. Ответ в модели - она работала не верно. Для тех кто мучается с такой же проблемой или похожей смотрите хелп внимательнее. Там говориться что QCompleter поддерживает QAbstractListModel (или както так зовется). Открывайте код этой модели и смотрите внимательнее как реализованны методы data, flags. Метод columnCount должен всегда возвращать 1.

Для примера вот код моей модели после того как она начала адекватно работать с QCompleter:

Код:
ModelUserDriverAutocomplete::ModelUserDriverAutocomplete(QObject *parent) :
    ModelAbstract(parent)
{
}

int ModelUserDriverAutocomplete::rowCount(const QModelIndex &parent) const
{
    return 5;
}

int ModelUserDriverAutocomplete::columnCount(const QModelIndex &parent) const
{
    return 1;
}

QVariant ModelUserDriverAutocomplete::data(const QModelIndex &index, int role) const
{
    if (index.row() < 0 || index.row() >= rowCount()) {
        return QVariant();
    }

    if (role == Qt::DisplayRole || role == Qt::EditRole) {
        if (index.row() == 0) {
            return QString("abcdefj");
        } else if (index.row() == 1){
            return QString("acdefdf2");
        } else if (index.row() == 2){
            return QString("acdefdf3");
        } else if (index.row() == 3){
            return QString("acdefdf4");
        } else if (index.row() == 4){
            return QString("acdefdf5");
        }
    }
    return QVariant();
}

QVariant ModelUserDriverAutocomplete::headerData(int section, Qt::Orientation orientation, int role) const
{
    return QVariant();
}

Qt::ItemFlags ModelUserDriverAutocomplete::flags(const QModelIndex &index) const
{
    if (!index.isValid()) {
        return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled;
    }

    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}

Ну а прикрутить сюда свои данные никому не составит труда я думаю. У меня так вообще это сериализованный объект с сервера :)