Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Qt] Tworzenie edytora map

Ostatnio zmodyfikowano 2011-02-16 15:07
Autor Wiadomość
programista12
Temat założony przez niniejszego użytkownika
» 2011-02-10 20:39:44
@up: Dzięki za linka, przydał się.
Mam kilka pytań:
1. Dodałem to projektu okno dialogowe do tworzenia nowego tilesetu. Problem jest w tym, że jak w MainWindow wywołam funkcję otwierającą dialog, to okienko dialogowe tylko mignie na ekranie i nic się nie dzieje. Oto kod funkcji wywołującej okno dialogowe:
C/C++
void MainWindow::NewTileset()
{
    newtileset newTilesetDialog( this );
    newTilesetDialog.show();
   
    if( newTilesetDialog.OKClicked() )
    {
        this->LoadNewTileset( newTilesetDialog.GetName() );
    }
}

W oknie dialogowym slot wykonywany po kliknięciu przycisku OK:
C/C++
this->SaveTileset();
this->ok_clicked = true;
this->accept();

Kiedyś w kodzie źródłowym jakiegoś programu w Qt znalazłem coś o tym, ale nie pamiętam jak to się robiło.

2. Mam strukturę Kafelek, w której przechowuję m.in. jego pozycję i wymiary. Chcę, żeby w momencie, gdy kursor znajduje się nad danym kafelkiem pojawił się rect będący zaznaczeniem, a gdy kursor jest nad innym kafelkiem, to żeby znikł.
Mógłby mi ktoś poradzić, jak to zrobić?

3. Jeżeli chcę na bieżąco wyświetlać mapę, to muszę w którymś momencie kodu używać funkcji update(), czy scena sama się aktualizuje? Jeżeli muszę używać update(), to w którym miejscu?
P-28153
pixelmaster
» 2011-02-10 22:14:57
1. Do dialogu wrzuć sobie QDialogButtonBox wtedy masz Ok i Cancel i robisz np. tak:
C/C++
//w klasie głównego okna
private:
QDialog * dialog;

//potem
class Dialog
: public QDialog
{
   
public:
    Dialog();
};

//w pliku cpp
void MainWindow::on_pushButton_clicked()
{
    dialog = new Dialog();
    dialog->setModal( true );
    dialog->show();
    if( dialog->exec() == QDialog::Accepted )
    {
        QMessageBox::information( this, "Ok", "Kliknięto OK", "Ok" );
    }
}

Dialog::Dialog()
{
    setMinimumSize( 200, 200 );
    resize( 300, 300 );
    setWindowTitle( "Nasz dialog" );
   
    QLabel * label = new QLabel( this );
    label->setGeometry( 15, 5, 290, 25 );
    label->setText( "To jest nasz dialog" );
   
    QDialogButtonBox * bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this );
    bbox->setGeometry( 15, 50, 290, 30 );
   
    connect( bbox, SIGNAL( accepted() ), this, SLOT( accept() ) );
    connect( bbox, SIGNAL( rejected() ), this, SLOT( reject() ) );
}

2.
gdzieś na devqt.pl (: O reklama) było jak włączyć aby qt non stop pobierało pozycję myszki. Potem robisz np tak że jak myszka jest nad kafelkiem jakimś to rysujesz nad nim kwadrat dając mu z-index np 1 (domyślnie itemki mają 0 więc kwadrat będzie nad nimi) i jak myszka znajdzie się nad innym kwadratem to ten item (kwadrat) przesuwasz (setPos).

3. Przy zdarzeniu mousePress Qt z automatu odświeża scenę
P-28162
programista12
Temat założony przez niniejszego użytkownika
» 2011-02-12 09:29:25
Dzięki, okno dialogowe działa jak trzeba. Jednak jak zwykle pojawiły się nowe problemy, a mianowicie:
1. Do sceny dodaję PixMapę. Jednak wyświetla się na środku sceny. Jak można zmienić pozycję dodawanej PixMapy? Próbowałem z scene->addPixmap(image)->setPos(0,0), ale to nie działa.
2. Do sceny mapy dodałem zdarzenia mousePress i mouseMove. W implementacji zdarzenia w pętlach for sprawdzałem nad którym kafelkiem znajduje się kursor i w celach testowych dodawałem recta (kod wyglądał tak samo w obu zdarzeniach). Wtedy wszystko działało dynamicznie (przytrzymywałem przycisk myszy i przesuwałem kursor i pojawiały się recty). Gdy dodałem rozpoznawanie przycisku myszy (w obu zdarzeniach), to za każdym razem muszę klikać, aby rect się pojawił, a chcę żeby to było dynamiczne. Oto kod zdarzeń:
C/C++
void Map::mousePressEvent( QGraphicsSceneMouseEvent * event )
{
    QPointF mp = event->scenePos();
   
    for( int i = 0; i < 32; i++ )
    {
        for( int j = 0; j < 24; j++ )
        {
            if( mp.x() >= this->kafelki[ i ][ j ].box.x() &&
            mp.x() <= this->kafelki[ i ][ j ].box.x() + 32 &&
            mp.y() >= this->kafelki[ i ][ j ].box.y() &&
            mp.y() <= this->kafelki[ i ][ j ].box.y() + 32 )
            {
                if( event->button() == Qt::LeftButton )
                {
                    this->SetTile( i, j, this->cur_id );
                    this->addRect( this->kafelki[ i ][ j ].box.x(), this->kafelki[ i ][ j ].box.y(), 32, 32, QPen( QColor( 255, 255, 255 ) ) );
                }
                if( event->button() == Qt::RightButton )
                {
                    this->SetTile( i, j, - 1 );
                    this->addRect( this->kafelki[ i ][ j ].box.x(), this->kafelki[ i ][ j ].box.y(), 32, 32, QPen( QColor( 255, 0, 0 ) ) );
                }
            }
        }
    }
}

void Map::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
{
    QPointF mp = event->scenePos();
    for( int i = 0; i < 32; i++ )
    {
        for( int j = 0; j < 24; j++ )
        {
            if( mp.x() >= this->kafelki[ i ][ j ].box.x() &&
            mp.x() <= this->kafelki[ i ][ j ].box.x() + 32 &&
            mp.y() >= this->kafelki[ i ][ j ].box.y() &&
            mp.y() <= this->kafelki[ i ][ j ].box.y() + 32 )
            {
                if( event->button() == Qt::LeftButton )
                {
                    this->SetTile( i, j, this->cur_id );
                    this->addRect( this->kafelki[ i ][ j ].box.x(), this->kafelki[ i ][ j ].box.y(), 32, 32, QPen( QColor( 255, 255, 255 ) ) );
                }
                if( event->button() == Qt::RightButton )
                {
                    this->SetTile( i, j, - 1 );
                    this->addRect( this->kafelki[ i ][ j ].box.x(), this->kafelki[ i ][ j ].box.y(), 32, 32, QPen( QColor( 255, 0, 0 ) ) );
                }
            }
        }
    }
}
P-28199
pixelmaster
» 2011-02-12 11:46:40
1. Ja dodawanie miałem tak zrobione (w scenie)
C/C++
editorItem * item = new editorItem();
QGraphicsPixmapItem * pix = new QGraphicsPixmapItem( item );
pix->setPixmap( QPixmap( pixMap ) );
item->setZValue( zIndex );
addItem( item );
item->setPos( x * tW, y * tH );

2. To przesuwanie Recta można chyba zrobić, że zapisujesz jego współrzędne i potem łapiesz item na tych współrzędnych i go przesuwasz
C/C++
QGraphicsItem * tmp = itemAt( x, y, QTransform() );
tmp->setPos( newPos );
P-28203
programista12
Temat założony przez niniejszego użytkownika
» 2011-02-16 15:07:52
Dzięki wszystkim za pomoc. Udało mi się napisać podstawowe funkcje edytora map, ale będę dalej go rozwijał. Zapraszam na stronę projektu na warsztat.gd. Temat zamykam.
P-28287
1 2 « 3 »
Poprzednia strona Strona 3 z 3