PDA

View Full Version : QListView within a plugin that is enabled/disabled: doesn't show?



postb99
18th February 2014, 09:43
Hello,

I'm using a custom Qt plugin with and API another team gave me. My understanding problem is about data binding and UI refresh.

The small plugin I use gets instantiated when I open the main GUI, then if I click on a menu item it gets enabled (visible).

My QListView doesn't show, I see an empty rounded frame with a border so there is some empty widget.

So here is some code to check what are coding guidelines I miss...

Thank you very much.



// constructor that gets called when opening up main GUI
AppletTutorial2Imp::AppletTutorial2Imp(QObject *parent) : XApplet(parent) {
m_enabled = false;
// Set up main widget
m_mainWidget = new QWidget();
m_mainWidget->setLayout(new QHBoxLayout());

m_listview = new QListView();
m_mainWidget->layout()->addWidget(m_listview);

// Assign main widget for applet to display
setWidget(m_mainWidget);
}




// code that gets called when choosing a menu item to display a specific module (plugin)
void AppletTutorial2Imp::setEnable(bool enable) {

if(m_enabled != enable) {
m_enabled = enable;
}

if(m_enabled) {
listDicomImages();
}
}




// Code that feeds QListView model and assign model to QListView
void AppletTutorial2Imp::listDicomImages() {

DicomImageModel model;
foreach... {
// Get object from memory query then:
model.addImage(image);
}
m_listview->setModel(&model);

}


Added after 15 minutes:

OK it seems to behave better if in my model class I have data retrieval that works. When I get an exception accessing non existing data it gets trapped. So I have more logs (I removed log statements from code pasted here) but still blank list view.

In my model I implemented only the following:




// constructor, destructor, then:

int DicomImageModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_dicomImages.size();
}

int DicomImageModel::columnCount(const QModelIndex & /*parent*/) const
{
return 6;
}

QVariant DicomImageModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
int col = index.column();

if(role == Qt::DisplayRole){
if (col == 0) return QString(m_dicomImages[row]->getId());
if (col == 1) return QString(m_dicomImages[row]->getDicomRef().getSeriesInstanceUID());

return QString("Row%1, Column%2")
.arg(row + 1)
.arg(col +1);
}

return QVariant();
}

void DicomImageModel::addImage(const XImageObjectPtr image)
{
m_dicomImages.push_back(image);
}



I changed the add item handling method in the model but list remains empty... so where is it wrong??



void DicomImageModel::addImage(const XImageObjectPtr image)
{
beginInsertRows(QModelIndex(), m_dicomImages.size(), m_dicomImages.size());
m_dicomImages.push_back(image);
endInsertRows();
}

anda_skoa
18th February 2014, 09:56
// Code that feeds QListView model and assign model to QListView
void AppletTutorial2Imp::listDicomImages() {

DicomImageModel model;
foreach... {
// Get object from memory query then:
model.addImage(image);
}
m_listview->setModel(&model);

}


If this is your actual code, then the model gets destroyed at the end of the method (variable "model" goes out of scope) and m_listview is now working with an invalid pointer.

Cheers,
_

postb99
18th February 2014, 10:51
Now my model is correct but my list is empty. So I still miss something, I guess my model updates aren't correctly notified to QListView?
Do I need to set some properties of list or can I use default "new QListView()"?

My model is now a member of plugin class.

I connected the plugin to a signal so that it does:



m_model.addImage(obj.dynamicCast<XImageObject>());


Called code:



void DicomImageModel::addImage(const XImageObjectPtr image)
{
int nbRows = m_dicomImages.size();
beginInsertRows(QModelIndex(), nbRows, nbRows);
m_dicomImages.push_back(image);
xLogWarning(XLogRecord::Type_User, QString(tr("Image %1 added").arg(image->getId())));
endInsertRows();
}


Thanks again

anda_skoa
18th February 2014, 14:37
The looks ok.
I assume you are deriving from QAbstractTableModel?

Do you rowCount() and columnCount() methods get called?

Cheers,
_

postb99
18th February 2014, 14:43
I indeed derive from QAbstractTableModel.

You got it, something is wrong with rowCount() and columnCount(), they're called at startup, when model is instantiated.

Then when I add an image to model, rowCount() gets called, but shows "0 row", then I have "1 object in model".

When I then click onto menu item link, my widget shows, but neither rowCount() nor columnCount() get called again...

anda_skoa
18th February 2014, 18:07
Hmm.

Make sure you are not having multiple instances of the model, i.e. that the model you are adding images to is the one that is set on the view.

Also try to verify the correct operations yourself, e.g.



qDebug() << "row count, emtpy model" << m_model->rowCount();

// add image

qDebug() << "row count, one image" << m_model->rowCount();

QModelIndex index = m_model->index(0, 0); // index for first image, id column
qDebug() << "index.isValid=" << index.isValid();

qDebug() << "image id=" << index.data(Qt::DisplayRole);


See also http://qt-project.org/wiki/Model_Test

Cheers,
_

postb99
19th February 2014, 11:18
Your guess was right, I was reinstantiating the model (half correction of wrong code)