[SOLVED] cellChanged doesn't work with QTimeEdit?



  • So i am setting the cellwidget via
    @QTimeEdit *end_time=new QTimeEdit(this);
    ui->tableWidget->setCellWidget(0, 0, end_time);@

    when i change the time of that timeedit signal "cellChanged":http://qt-project.org/doc/qt-4.7/qtablewidget.html#id-123d5435-33f2-4106-840f-7713158586be is not emitted ...


  • Lifetime Qt Champion

    Hi,

    AFAIK, cellChanged will only be emitted when you change the content of the cell not the widget you put in place of it.



  • [quote author="SGaist" date="1380576627"]Hi,

    AFAIK, cellChanged will only be emitted when you change the content of the cell not the widget you put in place of it.[/quote]

    Ok, so what do we do to check whether a widget on a cellwidget has changed?

    Someting like when cellactivated and cell deactivated check if it's the same? Any other ideas?


  • Lifetime Qt Champion

    I see two possibilities:

    • Use the timeChanged signal from your QTimeEdit
    • Create a QStyleItemDelegate that uses a QTimeEdit as editor


  • [quote author="SGaist" date="1380611472"]I see two possibilities:

    • Use the timeChanged signal from your QTimeEdit
    • Create a QStyleItemDelegate that uses a QTimeEdit as editor[/quote]

    I went with the first one since i am not experienced with the StyleItemDelegate

    i did someting like
    @QTimeEdit *end_time=new QTimeEdit(this);
    connect(end_time, SIGNAL(timeChanged(QTime)), this, SLOT(time_has_changed(QTime)));
    ui->tableWidget->setCellWidget(last_row, 3, end_time);@

    it works
    but i want to know in which row the qtimeedit changed... using currentitem,current row etc always returns 0x0 ...


  • Lifetime Qt Champion

    The only way I see would be to keep a map of your QTimeEdit and their position.
    You really should implement an item delegate, there's an example for the double spin box that you can use as a base.



  • [quote author="SGaist" date="1380632857"]The only way I see would be to keep a map of your QTimeEdit and their position.
    You really should implement an item delegate, there's an example for the double spin box that you can use as a base.[/quote]

    You mean the spinboxdelegate example? Ok i will take a look at it and will post my results tommorow ;)



  • I am confused with the "spinboxdelegate example":http://qt-project.org/doc/qt-4.8/itemviews-spinboxdelegate.html

    Mostly with the line
    @SpinBoxDelegate delegate;
    tableView.setItemDelegate(&delegate);@

    So what i am trying to do is to make the same exact example BUT, with a ui that i have added a tableview via the designer AND without any code at main.cpp.. So my mainwindow.cpp:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    #include <QStandardItemModel>
    #include <QSpinBox>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QStandardItemModel model(4, 2);
    ui->tableView->setModel(&model);
    
    //MainWindow delegate;
    //ui->tableView->setItemDelegate(&delegate);
    
    ui->tableView->horizontalHeader()->setStretchLastSection(true);
    
    for (int row = 0; row < 4; ++row) {
        for (int column = 0; column < 2; ++column) {
            QModelIndex index = model.index(row, column, QModelIndex());
            model.setData(index, QVariant((row + 1) * (column + 1)));
        }
    }
    
    this->setWindowTitle(QObject::tr("Spin Box Delegate"));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    QWidget *MainWindow::createEditor(QWidget parent,
    const QStyleOptionViewItem &/
    option /,
    const QModelIndex &/
    index */) const
    {
    QSpinBox *editor = new QSpinBox(parent);
    editor->setFrame(false);
    editor->setMinimum(0);
    editor->setMaximum(100);

    return editor;
    

    }

    void MainWindow::setEditorData(QWidget *editor,
    const QModelIndex &index) const
    {
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->setValue(value);
    

    }

    void MainWindow::setModelData(QWidget *editor, QAbstractItemModel *model,
    const QModelIndex &index) const
    {
    QSpinBox spinBox = static_cast<QSpinBox>(editor);
    spinBox->interpretText();
    int value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
    

    }

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

    The result is an empty tableview simple because of
    @ //MainWindow delegate;
    //ui->tableView->setItemDelegate(&delegate);@

    If uncomment these 2 lines they produce errors...


  • Lifetime Qt Champion

    You're not using it properly, it works in the example because the delegate scope is the main function. In your case, it's destroyed at the end of the constructor (and so should be your model).

    Why do you have a MainWindow as delegate in your MainWindow that is a QMainWindow ?



  • You are right about the model, i put it out of the constructor and it worked ;)

    [quote author="SGaist" date="1380728064"]
    Why do you have a MainWindow as delegate in your MainWindow that is a QMainWindow ?[/quote]

    Yeah these lines was the ones that confused me a lot...


  • Lifetime Qt Champion

    Then rename your delegate to something less confusing :) TimeEditDelegate for example :)



  • [quote author="SGaist" date="1380747885"]Then rename your delegate to something less confusing :) TimeEditDelegate for example :)[/quote]

    What do you mean rename the delegate?

    @MainWindow delegate;
    ui->tableView->setItemDelegate(&delegate);@

    always produces an error of
    @C2664: 'QAbstractItemView::setItemDelegate' : cannot convert parameter 1 from 'MainWindow **' to 'QAbstractItemDelegate *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast@

    How i am supposed to change this line?
    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {@


  • Lifetime Qt Champion

    You should have a separate class the is derived from QStyleItemDelegate, not just add the methods to your MainWindow class.



  • Ok i did..

    "result?":http://i.imgur.com/3gmpFUg.png

    "while we wanted something like":http://i.imgur.com/Xb0FiSJ.png

    mainwindow.h

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include "QTableWidgetItem"
    #include <QStyledItemDelegate>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;
    };

    class TableViewDelegate : public QStyledItemDelegate
    {
    Q_OBJECT

    public:
    TableViewDelegate(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;
    

    };

    #endif // MAINWINDOW_H@

    mainwindow.cpp

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    #include <QTimeEdit>
    #include <QDebug>
    #include <QStandardItemModel>

    QStandardItemModel model(4, 2);

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    ui->tableView->setModel(&model);
    
    TableViewDelegate delegate;
    ui->tableView->setItemDelegate(&delegate);
    
    ui->tableView->horizontalHeader()->setStretchLastSection(true);
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    TableViewDelegate::TableViewDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
    {
    for (int row = 0; row < 4; ++row) {
    for (int column = 0; column < 2; ++column) {
    QModelIndex index = model.index(row, column, QModelIndex());
    model.setData(index, QTime(12,04));
    }
    }
    }

    QWidget *TableViewDelegate::createEditor(QWidget parent,
    const QStyleOptionViewItem &/
    option /,
    const QModelIndex &/
    index */) const
    {
    QTimeEdit *editor = new QTimeEdit(parent);
    editor->setFrame(false);
    //editor->setMinimum(0);
    //editor->setMaximum(100);

    return editor;
    

    }

    void TableViewDelegate::setEditorData(QWidget *editor,
    const QModelIndex &index) const
    {
    QString value = index.model()->data(index, Qt::EditRole).toString();

    QTimeEdit *timeedit = static_cast<QTimeEdit*>(editor);
    timeedit->setTime(QTime::fromString(value));
    

    }

    void TableViewDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    const QModelIndex &index) const
    {
    QTimeEdit timeedit = static_cast<QTimeEdit>(editor);
    timeedit->interpretText();
    QString value = timeedit->time().toString();

    model->setData(index, value, Qt::EditRole);
    

    }

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

    i guess it has someting to do that TableViewDelegate doesn't have access to the ui, thus doesnt have access to the tableview.. What can i do for this?


  • Lifetime Qt Champion

    Your delegate is still destroyed at the end of the constructor



  • Yep you are right.
    Came back to mark as solved and say thanks ;)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.