PDA

View Full Version : QGraphicsView and item focus



Micawber
22nd June 2007, 13:46
Hello,

This is my first post so please be gentle. :)

I am having trouble getting keyPressEvents in a QGraphicsItem to work. What I have is a QDialog that builds (in the QDialog constructor) a QGraphicsView, creates a QGraphicsScene, initializes two QGraphicsItems (one is a pixmap the other is a sort of "cursor" that is displayed on top of the pixmap at various locations) then places the items in the scene and then sets the scene in the view. I then set the focus to the "cursor" object by setting setFlags( IsFocusable ) and calling Item.setFocus().

I have overridden the QKeyEvent method in my cursor and am looking for the 'N' key, but it doesn't show up.

I appreciate any help you may give as I don't have much hair left... :crying:

Here is some c++ code (I'm still learning c++ and probably will be for quite some time)...



// imap_cal_cursor.h
#include <QGraphicsItem>
#include <QObject>

class CImapCalCursor : public QObject, public QGraphicsItem
{
Q_OBJECT

public:
CImapCalCursor();
void keyPressEvent( QKeyEvent *event );
}


//imap_cal_cursor.cpp
#include "imap_cal_cursor.h"

#include <QGraphicsScene>
#include <QPainter>
#include <QStyleOption>
#include <QKeyEvent>

#include "syslog.h"

CImapCalCursor::CImapCalCursor() : QObject(), QGraphicsItem()
{
}

void CImapCalCursor::keyPressEvent( QKeyEvent *event )
{
switch (event->key()) {
case Qt::Key_N:
syslog( LOG_DEBUG, "DEBUG: Received Key_N event" );
break;
}
}


// calibration_dialog.h
#include <QDialog>
#include <QDialogButtonBox>
#include "imap_cal_image.h"
#include "imap_cal_cursor.h"

class CCalibration : public QDialog
{
Q_OBJECT

public:
QDialogButtonBox *buttonBox;
QGraphicsView *graphix_area;

protected:
class CImapCalImage Image;
class CImapCalCursor cur;
QGraphicsScene *Scene;
QList< QPoint > list;
int current_list_index;
QGraphicsPixmapItem *pixmapItem;

public:
CCalibration( QWidget * parent = 0, PEZG_COMMBLK EZGSharedMemPtr = NULL );
};


//calibration_dialog.cpp
#include <QtGui>
#include <QColor>

#include "calibration_dialog.h"
#include "syslog.h"

CCalibration::CCalibration(QWidget * parent, PEZG_COMMBLK EZGSharedMemPtr )
: QDialog(parent)
{
PIM_DIGBUFFER SourceImagePtr;
imageHeader *SourceImageHeaderPtr;
unsigned char *SourceImageDataPtr;

SourceImagePtr = &EZGSharedMemPtr->sImProcDigBuffer;
SourceImageHeaderPtr = &SourceImagePtr->Header;
SourceImageDataPtr = SourceImagePtr->image;

setObjectName(QString::fromUtf8("Calibration_Dialog"));
buttonBox = new QDialogButtonBox( this );
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(400, 630, 161, 32));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialo gButtonBox::NoButton|QDialogButtonBox::Ok);

graphix_area = new QGraphicsView( this );
graphix_area->setObjectName(QString::fromUtf8("graphix_area"));
graphix_area->setGeometry(QRect(20, 40, 951, 571));
graphix_area->setCacheMode(QGraphicsView::CacheBackground);
graphix_area->setRenderHint(QPainter::Antialiasing);

Scene = new QGraphicsScene( this );

Image = CImapCalImage( SourceImageDataPtr, SourceImageHeaderPtr->imWidth, SourceImageHeaderPtr->imHeight, QImage::Format_Indexed8 );
Image.GenerateColorMap();
pixmapItem = Scene->addPixmap( QPixmap::fromImage( Image ) );

list = Image.ScanForPoints();
if( list.isEmpty() || list.size() == 0 ) {
syslog( LOG_ERR, "ERROR: ScanForPoints returned empty list" );
current_list_index = -1;
}
else {
current_list_index = 0;
Scene->addItem( &cur );
cur.setZValue( 10 );
cur.setPos( pixmapItem->mapToParent( list[ current_list_index ] ) );
cur.setFlag( QGraphicsItem::ItemIsFocusable );
}

graphix_area->setScene( Scene );
Scene->setFocusItem( &cur );

QSize size(988, 684);
size = size.expandedTo(minimumSizeHint());
resize(size);
}

Gopala Krishna
22nd June 2007, 15:28
Hello,

This is my first post so please be gentle. :)
Welcome to the qtcentre! :)


I am having trouble getting keyPressEvents in a QGraphicsItem to work. What I have is a QDialog that builds (in the QDialog constructor) a QGraphicsView, creates a QGraphicsScene, initializes two QGraphicsItems (one is a pixmap the other is a sort of "cursor" that is displayed on top of the pixmap at various locations) then places the items in the scene and then sets the scene in the view. I then set the focus to the "cursor" object by setting setFlags( IsFocusable ) and calling Item.setFocus().

I have overridden the QKeyEvent method in my cursor and am looking for the 'N' key, but it doesn't show up.


Well i think , the cursor item is sensing key events properly but syslog's output should be invisible for some reason. I wrote a small example and this works fine in windows. I just used message box to make sure i get feedback when a key is pressed. Here is code

#include <QtGui>

class KeyReceiver : public QGraphicsEllipseItem
{
public:
KeyReceiver(const QRectF& rect) : QGraphicsEllipseItem(rect)
{
setFlags(ItemIsMovable | ItemIsFocusable | QGraphicsItem::ItemIsSelectable);
}

void keyPressEvent ( QKeyEvent * event )
{
if(event->key() == Qt::Key_N)
QMessageBox::warning(0,"dg","HF");
QGraphicsEllipseItem::keyPressEvent(event);
}
};

int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QGraphicsScene scene(0,0,1000,800);
KeyReceiver *r = new KeyReceiver(QRectF(10,10,100,80));
scene.addItem(r);
QGraphicsView view(&scene);
view.show();
r->setFocus();
return app.exec();
}

Micawber
22nd June 2007, 19:09
I tried calling QMessageBox in the keyPressEvent method but still no dice.

I thought that perhaps since the dialog was still under construction and the items not yet visible, the calls to setFocus were being ignored. So I added a SetFocus method to my extended QDialog class and called it from my main application after I called show(). Still no dice.

Obviously I am not understanding some key concept either in Qt or in C++.

Micawber
22nd June 2007, 20:36
OK some more information...

If I change my cursor class such that it is only a descendant of QGraphicsItem (remove the QObject ancestry and the timer stuff) it works. Any clue as to why having QObject ancestry would cause it to break??? :confused:

I need the timers and to emit signals.