Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Делегат: поле ввода и кнопка
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
kunashir
День добрый!
Потребовалось использовать такой делегат: ну сделал свой класс, наследник от QFrame, на нем разместил Layout, QLineEdit и QPushButton. В делегате этот класс использовал в качестве редактора - все вроде отлично, при начале редактирования ячейки QTableView появляется QLineEdit и QPushButton - но если сразу попытаться нажать на кнопку, редактирования прекращается и редактор закрывается, а когда сперва клацнуть по QLineEdit, то потом можно спокойно нажимать кнопку и закрытия редактора не происходит.
Собственно как сделать так чтобы сразу можно было жать на кнопку?
В идеале должно быть как при использовании QSpinBox в делегате - там то кнопки сразу можно щелкать.

Класс виджета:

Раскрывающийся текст


class CEditLineButton : public QFrame
{
    Q_OBJECT
public:
    explicit CEditLineButton(QWidget *parent = 0);
    ~CEditLineButton ();
    void setTextToEditLine (QString text);
signals:
    void clickButton ();

public slots:
  
private slots:
    void clicked ();
private:
    QLineEdit *lineEdit;
    QToolButton *button;
    QHBoxLayout *layout;
};

//реализация
#include "ceditlinebutton.h"

CEditLineButton::CEditLineButton(QWidget *parent) :
    QFrame(parent)
{
    setFrameShape(QFrame::NoFrame);
    lineEdit = new QLineEdit (this);
    button = new QToolButton (this);

    layout = new QHBoxLayout (this);
    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(lineEdit);
    layout->addWidget(button);
    button->setSizePolicy (QSizePolicy::Fixed,QSizePolicy::Minimum);
    lineEdit->setSizePolicy( QSizePolicy::Preferred,QSizePolicy::Preferred);
    connect (button, SIGNAL (clicked()), this, SLOT (clicked()));
    button->setText("...");
    //lineEdit->setFocus();
   lineEdit->setReadOnly(false);

   // lineEdit->setFocusProxy(button);
}

CEditLineButton::~CEditLineButton()
{
    delete lineEdit;
    delete button;
}



void CEditLineButton::clicked()
{
    emit clickButton();
}

void CEditLineButton::setTextToEditLine(QString text)
{
    lineEdit->setText(text);
}




Делегат:
Раскрывающийся текст

// Класс-делегат, который реализует интерфейс доступа к справочнику
// когда класс CCatalogPerson участвует как ссылочный (пример, класс Пользователи)
class DelegatPerson : public QItemDelegate
{
    Q_OBJECT
public:
    DelegatPerson (int id, QObject *parent = 0);
    QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData (QWidget *editor, const QModelIndex &index) const;
    void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void updateEditorGeometry (QWidget *editor,
                              const QStyleOptionViewItem &option, const QModelIndex &index) const;
    virtual void paint (QPainter *painter,
                const QStyleOptionViewItem& option, const QModelIndex& index ) const;
public slots:
    void showPesonCatalog ();
private:
    CCatalogPerson catPerson;
   // ViewPerson *editor;
};

//реализация
DelegatPerson::DelegatPerson (int id, QObject *parent)
    : QItemDelegate (parent)
{
    //TODO: в дальнейшем нужно реализовать чтобы
    //в форме справочника текущим был элемент с id
}

QWidget *DelegatPerson::createEditor(QWidget *parent,
                                     const QStyleOptionViewItem &option, const QModelIndex &index) const
{

    CEditLineButton *editor = new CEditLineButton (parent);
    editor->setTextToEditLine(index.data(Qt::EditRole).toString());
   // editor->installEventFilter(const_cast<DelegatPerson*> (this));
    connect (editor, SIGNAL (clickButton()), this, SLOT (showPesonCatalog()));
    //connect (this, SIGNAL (commitData(editor)), this, SLOT (showPesonCatalog()));
    return  editor;//layout->widget();
}

void DelegatPerson::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    CEditLineButton *myEdit = static_cast<CEditLineButton*> (editor);
    myEdit->setTextToEditLine(index.data(Qt::EditRole).toString());
}

void DelegatPerson::setModelData(QWidget *editor,
                                 QAbstractItemModel *model, const QModelIndex &index) const
{


}

void DelegatPerson::updateEditorGeometry(QWidget *editor,
                                         const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);

}

void DelegatPerson::paint (
            QPainter *painter,
            const QStyleOptionViewItem& option,
            const QModelIndex& index ) const {

    QString text;
    QRect rect;
    QVariant value;
    QStyleOptionViewItemV2 opt = setOptions(index, option);

    value = index.data(Qt::DisplayRole);
    text =  value.toString();//QLocale().toString(value.toString());
    opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
  // painter->drawText();
    drawDisplay(painter, opt, opt.rect, text);

}

void DelegatPerson::showPesonCatalog()
{
    ViewPerson *personTable = new ViewPerson ();
    personTable->setModel(catPerson.getModel());
    personTable->setItemDelegate(new QSqlRelationalDelegate (personTable));
    personTable->setAlternatingRowColors(true);
    personTable->show();
}

PAFOS
попробуй в методе createEditor дать QLineEdit фокус ввода (метод void QWidget::setFocus ( Qt::FocusReason reason ))

или в классе CEditLineButton переопредели метод focusInEvent(), где дай фокус строке ввода. Получается, что при клацании на ячейку в представлении, создается делегат и ему сразу же кидается фокус ввода. В данном случае мы попадем в метод CEditLineButton::focusInEvent() и передадим этот фокус строке ввода
kunashir
PAFOS, спасибо за совет!

Наше следующее решение http://labs.qt.nokia.com/2007/06/06/lineed...a-clear-button/
кнопка в поле ввода. Сам изначально хотел сделать так, но у меня текст подлезал под кнопку, а по ссылки все уже решено. Правда там кнопка используется для отчистки поля, но повесить на нее свое действие не сложно.
software developer
Если в методе делегата QStyledItemDelegate::createEditor() для созданного виджета вызвать Qwidget::setFocusPolicy(Qt::StrongFocus), то все будет работать как надо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.