[Qt-interest] Using QAbstractTableModel with Custom Class

Andre Somers andre at familiesomers.nl
Wed Jun 30 14:13:20 CEST 2010


On 30-6-2010 12:43, Bill Moo wrote:
> Hello List,
>
> I have a class that does some work, and this work runs on internal 
> threads. In order to keep the user informed of the progress of each 
> instance I thought that by using a Model based QTableView I could 
> eliminate some of the hard work.
>
> What I want to do a to create a QMap < int, Worker * > where the int 
> is the row number in view and the Worker * is an instance my class 
> that does all the hard work. However, what I can't get my head round 
> (assuming it is even possible) is how do I display the Worker's 
> internal member variable values in the grid? (as some of these are 
> updated by the internal processes).
>
> So assuming for example my QMap contained wto entries what I'd want to 
> see in the QTableView are two rows by x rows (with headers). Column 0 
> would display the name of the file currently being processed, the next 
> column would display the number of lines to process in this file, the 
> third column would display the number of rows processed so far.
>
> Is this even possible, or is it the Worker that needs to be a 
> derivative of QAbstractTable | Item Model I have googled of course but 
> I've not found anythign that comes close.
Totally possible, and doable.

As you are not dealing with a hierarchical model, I'd go for 
QAbstractTableModel as the base class. As Mandeep mentioned, you start 
with reimplementing the basic methods of that class: rowCount(), 
columnCount() and data(). As the documentation mentions, you should 
probably also reimplement headerData(). That would allow you to set the 
headers for the table you want to make.

Your implementation should have access to the class that 
contains/manages the threads that do the work.

Your rows() reimplementation would returns the number of treads that you 
have working, that is QMap::count() in your case.
Your columns() would return the number of properties you want to show 
for each of them, 3 in your case.
Your data() would access the information you need from the Workers. I 
think you can get away with just reading the values, even if they are 
not protected by a mutex, but you should test that I guess.

Your workers do not need to be adjusted at all. The model you are 
creating is just an interface you implement that you can use to query 
data from your internal system for display later on. So, it needs to be 
able to access that data, but it does not need any inheritance 
otherwise, nor do the classes that actually provide the data need to 
know about it if the information you want to display is available in 
their public interface. So, to answer your question "how do I display 
the Worker's internal member variable values in the grid", I would 
suggest you add at least read access to those values in the public 
interface of your workers. Just provide a int lineCount() const; 
function, for instance.

Then, you probably also want to make the display update when the workers 
make progress, right? So, fit your workers to emit signals when 
something happens that the outside world may care about, such as changes 
in what file is being worked on or the current line number. Your model 
can connect to those signals. I would use a QSignalMapper inside the 
model to map the worker back to a row number. Then, you can have your 
model emit the dataChanged() signal to notify the views that the data 
has changed.

André

P.S.
For spicing things up a little but, you could look into displaying a 
progress bar in the last column. Qxt provides a delegate that can do that.

-- 
Nokia Certified Qt Developer.
Interested in Qt related job offers or freelance Qt consulting work.




More information about the Qt-interest-old mailing list