PDA

View Full Version : Disable row/rows in QTableView



scott_hollen
25th March 2011, 21:17
This will be a softball to all you experts...

I have found examples of code that will allow the disabling of certain columns within a QTableView populated by a QSqlTableModel but not much for a row and I'm wondering if I can follow this: http://www.qtcentre.org/threads/36060-how-to-disbale-a-column-in-a-QTableView?highlight=how%2Bto%2Bdisable%2Ba%2Bcolu mn

What I'm trying to do is populate a tableview with non-editable data, but when the user clicks on a "New" pushbutton, a new row is created in the model that is editable. Rows will remain editable until a submitAll() is called at which time they can't be edited anymore....

Thanks!


scott

AlexSudnik
25th March 2011, 22:52
The post you've found actually explains everything you need...View's EditTriggers allow you to control the global "editability" of the shared model.Since you don't want user to edit anything before row is created:



void CustomWidget::setViews()
{
//...

QTableView customView;

customView->setEditTriggers(QAbstractItemView::NoEditTriggers) ;

//...
}



More precise control over editing can be achieved via the model class itself.

Take a look at the post's code snippet (the one with the ManifestModel class).The flags(...) method is the one the does the primary job of setting items' "editability" and other properties. Your model's class flag() method might look like this:


Qt::ItemFlags CustomModel::flags ( const QModelIndex & index ) const
{

if( index.row() == ActiveRow ) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;

else return Qt::ItemIsEnabled | Qt::ItemIsSelectable;

}


Where ActiveRow is set when a slot connected with the " "New" pushButton " will be invoked:


void CustomWidget::newButton_Slot()
{

// create new rows //

customModel->setActiveRow(...);

}

scott_hollen
26th March 2011, 00:09
Holy, cow, you mean I'm on to something for a change??? :) Thanks so much!


scott

scott_hollen
28th March 2011, 01:51
Okay, maybe I've been watching too much basketball but I may be overworking this problem...While I understand completely what it is I'm *trying* to do I'm having understanding exactly what it is I need to do...

You reference "ActiveRow" but is this just a shorthand reference to my current active row in my model? To keep things on the simple, what I'd like to do is on the newButton_slot() activate the row, and then whenever submitALL() is performed I can set NoEditTriggers on my tableview...

Is it possible to attack this problem thru the view?

Thanks and sorry for the ignorance...



scott

AlexSudnik
28th March 2011, 10:50
I used ActiveRow variable to store the last row number,but it's not really necessary.Don't quite understood your last question but...seems like you need a little bit more explanation.
This is what your main widget class might look like,for time sake i'm gonna put all in constructor :


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

view=new QTableView;

model=new CustomModel( rows , columns , this)

view->setModel(model);

createButton=new QPushButton(tr(" New Row "));

connect(createButton,SIGNAL( clicked() ),SLOT( createRow_Slot() ) )

submitButton=new QPushButton(tr(" Submit Row "));

connect(createButton,SIGNAL( clicked() ),SLOT( createRow_Slot() ) )

QVBoxLayout *mainLayout=new QVBoxLayout(this);
mainLayout->addWidget(view);
mainLayout->addWidget(createButton);
mainLayout->addWidget(submitButton);
}

Buttons' slots might look like this:


void MainWidget::createRow_Slot()
{
if ( model->addRow( model->rowCount() ) )
view->setEditTriggers(QAbstractItemView::DoubleClicked); // make sure that view will be editable once the row is added

else // call an error message or smth. to indicate a problem while inserting a new row

}
void MainWidget::submitRow_Slot()
{

view->setEditTriggers(QAbstractItemView::NoEditTriggers) ; // once submitted,the view will be no longer editable

}

And finally you CustomModel class.The only method you need is "flags",so this is it:


Qt::ItemFlags flags(const QModelIndex &index) const
{
if(index.row()== ( rowCount() -1 ) )
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; //only last row is editable
else
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;

}

scott_hollen
28th March 2011, 15:59
Ahhhh...Now, I see...Looks like I was about 95% there -- the "if(index.row()== ( rowCount() -1 ) ) " part is where I was tripping up...I haven't really used ItemFlags yet (only been using Qt for about 3 months part time)...Some things are so obvious in hindsight...

Throughout the rest of my app I've handled the enable/disabling of the data easily because I was using a master/detail design...Once data was submitted to the DB, then just disabled the entire tableview; a "new" button click resulted in me turning it back on, but this last section is just once large tableview...

I appreciate the push!


scott

scott_hollen
28th March 2011, 19:16
Works perfectly!!! Put in the line,
if(index.row()== ( rowCount() -1 ) ) and everything worked great -- thanks for that direction!


scott