Qt myszka w QGraphicsView

0

Witam

Mam problem z odczytaniem współrzędnych kliknięcia myszki na scenie.

Chciałem użyć funkcji QPoint buttonDownScreenPos ( Qt::MouseButton button );
Ale ciężko mi znaleźć przykład w internecie tej funkcji...

próbowałem tak :

plik.h

    QGraphicsScene      *scene;
    QGraphicsView       *view;
    MyItem              *square[9];

    int                 mouseX,
                        mouseY;

    QPoint              mouse_pos;

protected :

    QPoint buttonDownScreenPos ( Qt::MouseButton button );

    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);;

plik .cpp


QPoint MainWindow::buttonDownScreenPos(Qt::MouseButton button)
{
    QPoint point;
    return QPoint(point);
}

void MainWindow::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    MainWindow::mousePressEvent(event);

    mouse_pos = buttonDownScreenPos (Qt::LeftButton);

    mouseX = mouse_pos.rx();
    mouseY = mouse_pos.ry();

    QString tmp;

    ui->label_X->setText(tmp.number(mouseX));
    ui->label_Y->setText(tmp.number(mouseY));
}

dodam że MainWindow jest zwykłą formatka a grafike wyświetlam w Graphics View.

Na razie tyle mam i wiem że to jest źle, próbowałem na inne sposoby i nie wiem co zrobić aby zadziałało.

0

Dobrze myślałeś,ale z wykonaniem ciut słabiej.
Trzeba to zrobić tak:
1.Przeimplementuj QGraphiscScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
2.A we wnętrzu tej funkcji użyj e->buttonDownScenePos(twójKlawisz)

Twój błąd polega generalnie na tym,że chcesz przeimplementowywać mousePressEventa od QMainWindowa,który nic wspólnego z tym czego chcesz nie ma.

Możesz też zainstalować sobie Event Filter na swoją scenę skoro jest QObjectem,a po przechwyceniu QGraphicsSceneMouseEventu postępujesz dalej tak samo jak w 1 przypadku.

0

Hmm a więc aby zrobić punkt pierwszy muszę stworzyć klasę dziedziczącą po QGraphicsScene ? czy da się mousepressevent odpowiednio przerobić na widget graphics view na formatce ?

Chociaż tak chyba od nowa przepisze projekt na pod pełne QGraphicsView chociaz jest tylko do nauki , a pytam z ciekawości :)

0

Dokładnie tak,trzeba odziedziczyć QGraphicsScene.
Co do przerabiania,to jakby się uparł też by się dało,obczajaj metody mapTo...(np mapToScene) od widgeta,graphics view i scene oraz to,co tam assistant będzie podpowiadał.
No i zawsze możesz stworzyć sobie obiekt filtrujący i użyć scene.setFilter(filterObject)

0

Witam

starałem przepisać kod na nowo ale problem pojawił się już na początku

Teraz całość to czyste QGraphicsView, stworzyłem klasę dziedzicząca po QGraphicsScene wszystko się kompiluje ale gdy klikne na okno to wywala

"Program nieoczekiwanie przerwał pracę .... zakończone kodem -1073741819"

Wiem dokładnie która linijka powoduje błąd ale nie wiem dlaczego

main

int main( int argc, char **argv )
{
    QApplication app( argc, argv );

    MyWindow    mw;

    QGraphicsView *view = new QGraphicsView(&mw);

    view->resize(400,400);
    view->show();

    return app.exec();
}

plik.h bez zmian praktycznie, MyWindow to czysta klasa dodałem tylko

: public QGraphicsScene

plik .cpp

MyWindow::MyWindow()
{
    scene = new QGraphicsScene(this);
    scene->setSceneRect(0,0,400,400);
}

void MyWindow::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    MyWindow::mousePressEvent(event);  // ta linijka wywala błąd nawet z wykomentowana reszta kodu

    /*
    event->buttonDownScenePos (Qt::LeftButton);

    mouseX = mouse_pos.rx();
    mouseY = mouse_pos.ry();
    scene->addEllipse(mouseX,mouseY,50,50); // dla testu */ 

}
0

zupełnie nie tak:
-ustawianie scenie parenta nie ma sensu,bo o ile mnie pamięć nie myli i tak view ustawi się sam na jej parenta
-nie wywołujesz setScene na widoku

Prawidłowo winno to wyglądać tak:

class YourWindow : public QMainWindow
{
    QGraphicsView view;
    YourGraphicsScene scene;//to ta przeimplementowana wg powyższych wskazówek scena

public:
   YourWindow(QWidget *parent=0,Qt::WindowFlags flags=0):QMainWindow(parent,flags)
   {
       view.setScene(&scene);
       view.setSceneRect(0,0,400,400);
       setCentralWidget(&view);
   }
};

Poza powyższym kodem więcej klasy okna nie ruszaj,myszę masz obsłużyć tylko i wyłącznie w YourGraphicsScene::mousePressEvent()

0

To samo dalej :(

Mam teraz klase główną okna dziedziczącą po QMainWindow identyczna jak Ty napisałeś, w konstuktorze tej klasy tworze obiekt swojej klasy MyScene która dziedziczy po QGraphicsScene, w MyScene trzymam mousepressevent i znów wywala na :

void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    MyScene::mousePressEvent(event);
}

reszta kodu zupełnie czysa.

0

Zapodaj cały projekt w .zip-ie,bo to jakieś cuda się u ciebie dzieją.Spartoliłeś coś w innej części zapewne.
Zrobiłem testowy projekt u siebie (Vs2003+Qt addon,Qt 4.5.0) i jakimś sposobem działa.

Albo lepiej,obacz mój testowy projekt i sam porównuj w swoim coś skopał.

0

nie wiem gdzie można tu jeszcze cos zepsuć, projekt prawie czysty

http://speedy.sh/PXsZN/kolko04.zip

0

Uff znalazłem błąd :) dzięki za program wszystko działa i było prawie identyczne poza :

QGraphicsScene::mousePressEvent(e);  // dobra wersja
MyScene::mousePressEvent(e);  // zla wersja

Czyli zamiast QGraphicsScene podawałem nazwe mojej klasy ;/

kodu nie dałem bo wyskakiwało mi nie dozwolony octet-stream mimo że miałem same pliki .h .cpp .pro spakowane w .zip

Jade dalej, dzięki jeszcze raz

1 użytkowników online, w tym zalogowanych: 0, gości: 1