[Megoldva, köszi mindenkinek]Folyatatás! qt-ben click pozíciója, a qimagen.

 ( emberk | 2010. január 25., hétfő - 16:25 )

Sziasztok.

Új hiba, (vagy mi) amibe ütköztem. A QMouseEvent-nek nincs semmilyen meghívható függénye, legalábbis a QT-creator szerint. míg pl a
int x_pos=QCursor::pos().x(); minden hiba nélkül lefut, és megkapom az egér pozícióját (ami nekem nem sok semmire jó), addig a
int x_pos=QMouseEvent::pos().x() a következő hibaüzenetet adja:
/home/ek/work/qt/q/ocv1.cpp:405: error: incomplete type ‘QMouseEvent’ used in nested name specifier. Ezzel a hibaüzenettel (ami simán lehet hogy a QT-kezdő mivoltomból fakad) nem tudok mit kezdeni, de a QT-creator sem ad semi függvényt a QMouseEvent:: után. Ja és ez a fenti sor egy QT-tutoriálból van. Ötlet? Mégegyszer köszi előre is mindent.

Sziasztok.

Az lenne a feladatom egyik része, hogy egy qimage-képen 2 click-el ki tudjak vágni a képből a két pont által meghatározható négyzet (függőlegesek vízszintesek, persze. Semmi extra. Bal felső jobb alsó sarok, vagy fordítva, azt úgy is sorba rakom) alatti területet. A kivágás, stb az sima ügy, olyat már csináltam GTK-ban, tehát a metódus megvan. Igazából csak a függvény nevét nem tudom, hogy ha klikkelek, akkor kapjak egy x-y koordinátát. Valamit az egy scrollarea háttere amire klikkelgetek, és annak ez a függvényt még meg is kellene hívnia a 2.clickre, ami egy globális változóval sima ügy, de lehet van elegánsabb is.

Köszi előre is.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

UP!

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

http://qt.nokia.com/doc/4.6/qmouseevent.html
const QPoint & QMouseEvent::pos()

Az alkalmazásban valósíts meg egy ezt adó függvényt (pl. QWidget::mousePressEvent(), QWidget::mouseReleaseEvent(), QWidget::mouseDoubleClickEvent() és QWidget::mouseMoveEvent()), és ott mentsd el ezt az értéket.

--
Elder Scrolls

Ok. Ez kellett köszi. Én tippelgettem ezerrel, hogy Qimageclicked, pressed........ Így sima ügy.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Még egy kis gond. Az hogy egy adott elemen milyen pozicóba klikkelek az nem meghatározható valahogy? Mert ez így elég kényelmetlen, hogy mindíg a képernyőkép pozícióját kapom meg. Ja és ráadásul csak scrollarea-n fér el egy 8XXX*8XXX-es kép (zabálja is a memóriát a gép rendesen, de ez van ez kell.) úgy hogy tetszőleges képerészletet max felbontásban tudjak nézni, tehát így végképp használhatatlan, mert fogalmam sincs hogy a felhasználó majd hova tekeri a képet. Tehát nekem a görgetődboz poziciói kellenének

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Nézd meg a QWidget osztály pos() függvényét! Utána egy vagy két kivonás...
--
http://www.naszta.hu

Ha jól emlékszem, akkor így van: létrehozol egy QScrollAreát (mondjuk Designerben) és a widget tartalmát pedig implementálod, és annak a mouseMove esemény pos() változója már jó lesz egy setFixedSize() hívás után.

Szóval:
- Hozz létre egy új osztály (NC lesz a neve most) és QWidgetből örököljön. Erre kerül majd a rajz
- QScrollArea valahol, és abba egy QWidgetet rakj, amit jobb klikkel és Promote to...-val NC-vé varázsolsz
- Az NC kódjában meghívod valamikor a QWidget::setFixedSize(const QSize &) függvényt, és onnantól kezdve lesz görgetősávod a QScrollAreán, és az NC mouseMoveEvent függvény argumentumának pos() függvénye pedig a neked jó értékekkel tér vissza.

--
Elder Scrolls

Figyelem! Hozzá nem értő ötlet következik. Ha az ablak egy adott X * Y méretű területén jelenítenél meg a képből egy X * Y méretű részt, akkor a kép elmozdítása után is egyértelmű lenne a kattintások pozíciója.

:)

UP!
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Egy UP az éjszakás műszaknak. :) Továbbra sem találtam megoldást.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Egy tipp és nem több:

A QScrollArea::verticalScrollBar()->value() segítségével megkaphatod, hogy a a képen belül hova scrolloztak. (A horizontális érték természetesen horizontal.) A scrollbar minimum és maximum értékéhez hasonlítva ez a számot, arányaiban megkapod, hogy melyik részletét látják a képnek és ahhoz hozzá tudod matekozni a klikkelési pozíciót. Kicsit gány megoldás, de talán működhet, más most nem jut eszembe.

3-4 hete pont ugyanilyet írtam.

Egyszerűsítve a megoldás: írtam egy widget-et, ami megjeleníti a képet (pixelről pixelre, mindenféle transzformáció nélkül).

A saját widget-et ráraktam a QScrollArea-ra.

Innen a saját widget mouseReleaseEvent() slot-javal elmentettem az egérpozíciót. Transzformálni nem kellett, mert a saját widget QMouseEvent::pos()-ja már a kép koordinátáját adta vissza függetlenül attól, hogy a scrollbar hol állt.

Nekem pont az a bajom, hogy nem létezik QMouseEvent::pos(). Egyszerűen a QMouseEvent osztály létezik, de teljesen üres. nincs benne semmi meghívható fügvény.

UI:
Egy ökör vagyok. nem tettem be a qevent.h a header-ek közé, persze hogy akkor nincsenek az eventeknek fügvényei.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

google: QMouseEvent()

sokat segit. Amugy a headerek koze eleg a QMouseEvent-et, akkor mar hasznalhatod a pos()-fvet.

Egyszerűen a QMouseEvent osztály létezik, de teljesen üres. nincs benne semmi meghívható fügvény.

Az egy dolog, hogy az autocompletion/akármi nem mutatja, de azért ez durva, hogy a manual-t meg se nézted..

szerintem egy kicsit túlbonyolítod.
Egy eléggé Qt-lelkú megoldás:

- mainwindow, abba egy file / open, File / exit menu
- középre felteszel egy gridlayout-ba egy QScrollArea-t, abba egy QLabel-t
- ezt a QLabel-t promotálod QMyImageLabel-lé (jobbklikk promote), ebben lesz a szelekciós logika
- ez dob egy signal-t ha kész a szelekció (semmi trükközés nem kell a kattintási koordináták képkoordinátákká alakításához)
- ezt a signal-t elkapja a fő form és csinál vele amit akar

QMyImageLabel.h :

 
#include <QLabel>
class QMyImageLabel : public QLabel
{
    Q_OBJECT
public:
    explicit QMyImageLabel( QWidget* aParent = NULL ) : QLabel( aParent )
    {
        m_NumClicks       = 0;
        m_LastClickedRect = QRect( 0, 0, 0, 0 );
    }
signals:
    void rectDefined( const QRect& aRect );
protected:
    void mousePressEvent( QMouseEvent *ev );
protected:
    int   m_NumClicks;
    QRect m_LastClickedRect;
};

QMyImageLabel.cpp :

 
#include "QMyImageLabel.h"
#include <QMouseEvent>

void QMyImageLabel::mousePressEvent( QMouseEvent *ev )
{
	++m_NumClicks;

	if( m_NumClicks < 1 ) m_NumClicks = 1;
	if( m_NumClicks > 2 ) m_NumClicks = 1;

	switch( m_NumClicks ) {
	case 1:
		 m_LastClickedRect = QRect( ev->pos(), QSize( 0, 0 ) );
		 break;
	case 2:
		 m_LastClickedRect.setBottomRight( ev->pos() );
		 emit rectDefined( m_LastClickedRect );
		 m_NumClicks = 0;
		 break;
	}
}

mainwindow.h:

#include <QtGui/QMainWindow>
#include "ui_clickrectmainwindow.h"

class ClickRectMainWindow : public QMainWindow
{
	Q_OBJECT
public:
	ClickRectMainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
private slots:
	void on_label_rectDefined( const QRect& aRect );
	void on_action_Open_triggered();
	void on_actionE_xit_triggered();
private:
	Ui::ClickRectMainWindowClass ui;
};

manwindow.cpp:

#include "clickrectmainwindow.h"
#include <QImageReader>
#include <QFileDialog>

ClickRectMainWindow::ClickRectMainWindow( QWidget *parent, Qt::WFlags flags ) : QMainWindow( parent, flags )
{
	ui.setupUi(this);
}

void ClickRectMainWindow::on_actionE_xit_triggered()
{
	close();
}

void ClickRectMainWindow::on_action_Open_triggered()
{
	QString fileName = QFileDialog::getOpenFileName( this, "Open Image", "", "Image Files (*.png *.jpg *.bmp)" );
	if( fileName.isEmpty() ) return;
	QPixmap pm( fileName );
	ui.label->setPixmap( pm );
}

void ClickRectMainWindow::on_label_rectDefined( const QRect& aRect )
{
	QString msg = QString( "%1,%2 - w=%3, h=%4" ).arg( aRect.left() ).arg( aRect.top() ).arg( aRect.width() ).arg( aRect.height() );
	this->setWindowTitle( msg );
}

Ja közben megoldottam, de köszi. Én inkább a matekozást választottam, mert így csak két sor. úgy is egy 3-órás mérés alatt lesz néhány click.

void MainWindow::mousePressEvent(QMouseEvent *ev)
{
......
int hvalue = ui->scrollArea->horizontalScrollBar()->value();
QPoint clickpos=ev->pos();
int picturepos_x=(clickpos.x()+hvalue)*resize_rate;
.......
}

Természetesen a kép a bal felső sarokból indul.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.