PDA

View Full Version : QTimer



dragon
19th October 2008, 14:53
Hello anyone,

Iám using qt-4.4.1 with Windows XP.
I have subclassed QSqLTableModel into CustomSqlModel for the BackgroundRole for setting different colors in columns and Textalignment.
In the main implentation i use QTableview as model.
Everything works perfect.
I have also subclassed QItemDelegate for setting background color for a column with a certain value. ( see example code below).
Now my question is i want to blink the cells with a QTimer in the subclassed QItemDelegate.
Is this possible and can you give me some example code.
QTimer use Signal and a Slot but the paint constructor is public and not a slot.



#include "delegate.h"
#include <QPainter>
#include <QTimer>

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

int val = index.model()->data(index, Qt::DisplayRole).toInt() < 1 ;
if(index.column() == 8 && val )

{
painter->fillRect(option.rect, Qt::yellow);

}
else

QItemDelegate::paint(painter,option,index);
}




Thanks in advance.

wysota
19th October 2008, 15:03
Hmm... tough problem. Not because what you want is not possible -- it is quite easy. The real problem is where to implement it. Is blinking a feature of the model? Or maybe the view? Would you want the same cell to blink in all views showing it or only in a particular one? Answer to those questions depends on why you want cells to blink in the first place.

If you want blinking to be part of the model, then simply provide a custom slot for your model where you will change the background role of the item and emit dataChanged.

If you want blinking to be associated with a particular view, then you have to change the way the view renders cells - either through the delegate or somehow directly through the view. Remember that the delegate is shared for all items in a view and possibly between different views as well, so storing any information about blinking items in the delegate might not be a good idea. A possible nice solution in this case would be to provide a custom proxy model between your base model and the view so that you can control blinking from the proxy model in the same way as described earlier.

dragon
19th October 2008, 16:38
Hello wysota,

I want blink cells to be part of the model.

wysota
19th October 2008, 16:55
So simply change the background role of items you want to blink using a timer or a timerEvent. If you emit the dataChanged signal, all views will get updated.

dragon
19th October 2008, 17:24
Must i do that in the Main implentation or in the subclassed QSqltableModel.

Thanks in advanced.

wysota
19th October 2008, 20:02
The QSqlTableModel doesn't allow using the background role, so you'll need to provide support for it in the subclass. Your model has to return proper data from the data() method.

dragon
19th October 2008, 21:49
wysota thanks for your advice and time.

dragon
24th October 2008, 14:49
Iám still struggle to get the cells background to blink in the model with a timer.
I have a customslot declared in the customsqlmodel.h (see code below).


public:
CustomSqlModel(QObject *parent = 0);
QVariant data(const QModelIndex &index, int role) const;

public slots:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); // I don't no this is the right slot

private:
CustomSqlModel *model;



In my customsqlmodel.cpp(see code below).


CustomSqlModel::CustomSqlModel(QObject *parent)
: QSqlTableModel(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(dataChanged(const QModelIndex&, const QModelIndex&))); //Can i connect the timer to the dataChanged() slot on this way?
timer->start(1000);

//a custom slot
connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex &topLeft, QModelIndex &bottomRight)));
}

QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
{
QVariant value = QSqlTableModel::data(index, role);
if (role == Qt::BackgroundColorRole)
{
int val = index.model()->data(index, Qt::DisplayRole).toInt() < 1;
if(index.column() == 8 && val )
return qVariantFromValue(QColor(Qt::yellow)); // Want to blink these color with a timer into the custom slot dataChanged().
return qVariantFromValue(QColor(Qt::grey));
}

return value;
}

void CustomSqlModel::dataChanged(const QModelIndex &topLeft, QModelIndex &bottomRight)
{
// What to put here.
emit dataChanged(topLeft, bottomRight); //?
}



Can someone give my some example code.
I tried severall things but nothings works.
Thanks in advance.

wysota
24th October 2008, 16:39
Signal and slot signatures have to match, that's for sure.

dragon
24th October 2008, 17:38
Ok, I will recode my application to get it work.

wysota
24th October 2008, 21:50
I think you are making things overcomplicated. Try something like this:


void mymodel::timerEvent(QTimerEvent *te){
blinkon = !blinkon;
int topRow = rowCount();
int bottomRow = -1;
for(int i=0;i<rowCount();i++){
for(int j=0;j<columnCount();j++){
if(data(index(i, j), IsBlinkingRole).toBool()){
if(blinkon)
setData(index(i,j), Qt::red, Qt::BackgroundRole);
else
setData(index(i,j), QVariant(), Qt::BackgroundRole);
if(i<topRow) topRow = i; if(i>bottomRole) bottomRole = i;
}
}
if(bottomRow>=0)
emit dataChanged(index(topRow, 0), index(bottomRow, columnCount()-1));
}
Now it's enough to use startTimer with the blink period, initialize "blinkon" variable and set IsBlinkingRole on items you want to blink. Of course your model has to support both BackgroundRole and the custom IsBlinkingRole.

dragon
26th October 2008, 12:56
Thanks for the example code.
I,am using qt 4-4-1 (opensource).


if(data(index(i, j), IsBlinkingRole).toBool())

My CustomSqlModel support BackgroundRole but not IsBlinkingRole.
Must i create first a custom IsBlinkingRole.

Thanks in advance

wysota
26th October 2008, 14:53
Yes, you must implement that role for your model.

dragon
29th October 2008, 18:11
I have initialize "blinkon" variable like this:


static bool blinkon = true;

I have made on the top of my customsqlmodel.cpp a customRole IsBlinkingRole like this:


#include <QtGui>
#include <QTimerEvent>

#include "customsqlmodel.h"

const int IsBlinkingRole = Qt::UserRole;


I have a startTimer in my customsqlmodel.cpp like this:


CustomSqlModel::CustomSqlModel(QObject *parent)
: QSqlTableModel(parent)
{
startTimer(1000);
}

My question is how to set the items that i want to blink to my customRole in my data() method.
Normally i can use Qt::DisplayRole or Qt::BackgroundRole etc.

Thanks in advance.

dragon
15th November 2008, 14:27
Hello anyone,

Iám still struggle to set the items that i want to blink to my IsBlinkingRole in my data() method.


#include <QtGui>
#include <QTimerEvent>
#include "customsqlmodel.h"
const int IsBlinkingRole = Qt::UserRole;




if(role ==Qt:: BackgroundRole)
{
If(role == isBlinkingRole)
{
int val = index.model()->data(index, Qt::DisplayRole).toInt() < 1 ;
if(index.column() == 8 && val )
}
}


Thanks in advance

wysota
15th November 2008, 14:56
The above code makes no sense. If the first if is entered, the second isn't. So the inner if block never gets executed.

dragon
15th November 2008, 15:51
Can you give me some example how to set the items to the CustomRole.

Thanks in advance.

wysota
15th November 2008, 22:27
If you use a model that doesn't store custom data (like all sql models), you have to provide a container for them in the model and reimplement setData() to store the incoming data in the container.

dragon
16th November 2008, 14:15
Thanks for your time and advice.
I will look further on the net and the forum threads for setData() examples.