Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Nekron от Январь 12, 2010, 14:57



Название: Ханойские башни
Отправлено: Nekron от Январь 12, 2010, 14:57
Мне необходимо сделать программу-игру "Ханойские башни" кто не знает это вроде как 3 пирамиды на одной навешаны кольца другие пустые надо с  одной перевесить все кольца на другую, но при этом нельзя ложить большие на меньшие(они расположены изначально от большего к меньшему).

Проблема в следующем, мне необходимо реализовать перемещение колец с помощью Drag&Drop, для башен я использовал линии, а вместо колец push-батоны
Вопрос: как мне сделать чтобы их можно было перетаскивать с помощью мышки?


Название: Re: Ханойские башни
Отправлено: pastor от Январь 12, 2010, 15:08
Пушбфтонны это конечно хорошо, но я бы взглянул на Graphics View Framework. Пирамидами будут все теже линии, а вот в качестве колец QGraphicsItem (например QGraphicsRectItem)


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 12, 2010, 15:23
ммм тоесть в Display Widgets - Graphics View сделать их такихже размеров и заменить?
Спасиб ) а то сам думал что может лучшие варианты будут


Название: Re: Ханойские башни
Отправлено: pastor от Январь 12, 2010, 16:19
У тебя будет QGraphicsView, к нему цепляешь сцену (QGraphicsScene). На сцене отрисовываешь линии (башни) и кладешь также на сцену в нужном месте и количестве QGraphicsRectItem (кольца). Также выстави для QGraphicsRectItem флаг QGraphicsItem::ItemIsMovable:

Код
C++ (Qt)
setFlag(QGraphicsItem::ItemIsMovable, true);


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 12, 2010, 17:36
Пасиб, разобрался ) ух жаль ток через код только можно создавать квадраты а не в дизайнере.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 14, 2010, 17:17
Не пойму чтото в координатах для квадрата )
scene->addRect(QRectF(-100.0, -100.0, 50.0, 50.0));
вот последний две цифры я так понял за размер отвечают, а первые две как не изменяю ничего не меняется, и расположен всегда в центре, а мнеж надо расположить на пирамиде все квадраты, подскажите за что отвечают первые две, и как передвинуть квадрат плз )


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 14, 2010, 17:44
Не пойму чтото в координатах для квадрата )
scene->addRect(QRectF(-100.0, -100.0, 50.0, 50.0));
вот последний две цифры я так понял за размер отвечают, а первые две как не изменяю ничего не меняется, и расположен всегда в центре, а мнеж надо расположить на пирамиде все квадраты, подскажите за что отвечают первые две, и как передвинуть квадрат плз )

Уверены?
Вот такой код рисует 9 квадратиков в тех местах где и должен
Код
C++ (Qt)
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QApplication>
 
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QGraphicsView view;
   QGraphicsScene *scene = new QGraphicsScene();
   view.setScene(scene);
   scene->addRect(QRectF(-100.0, -100.0, 50.0, 50.0));    
   scene->addRect(QRectF(0.0, -100.0, 50.0, 50.0));    
   scene->addRect(QRectF(-100.0, 0.0, 50.0, 50.0));    
   scene->addRect(QRectF(0.0, 0.0, 50.0, 50.0));    
   scene->addRect(QRectF(100.0, 100.0, 50.0, 50.0));    
   scene->addRect(QRectF(0.0, 100.0, 50.0, 50.0));    
   scene->addRect(QRectF(100.0, 0.0, 50.0, 50.0));    
   scene->addRect(QRectF(-100.0, 100.0, 50.0, 50.0));    
   scene->addRect(QRectF(100.0, -100.0, 50.0, 50.0));    
   view.show();
   return a.exec();
}
 


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 14, 2010, 21:21
Да так складно вроде выходит ) но когда все зачеркиваю и оставляю только один из них нарисовать то рисует всеравно посередине независимо от координат. )
Ну да ладно ) главное мне действительно не один нужен.


Название: Re: Ханойские башни
Отправлено: ufna от Январь 14, 2010, 21:24
прочитай про фреймворк. Это не есть "рисует".


Название: Re: Ханойские башни
Отправлено: Dendy от Январь 14, 2010, 21:28
Это не он рисуется посередине, а сцена автоматически растягивается чтобы вмещать ровно все элементы. И если элемент один, то получается, что как будто посередине. Явно задавайте координаты сцены и будет вам счастье (-;


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 14, 2010, 21:31
А ясно ) жаль не учитывает линий что я на график вьев через дизайнер нарисовал


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 14, 2010, 21:49
еще подскажите, пожалуйста, вот в этой команде что ранее показывали

Код:
setFlag(QGraphicsItem::ItemIsMovable, true);

когда набираю его выводит ошибки

src\mainwindowimpl.cpp:18: error: `ItemIsMovable' is not a member of `QRectF'
src\mainwindowimpl.cpp:18: error: `setFlag' was not declared in this scope
src\mainwindowimpl.cpp:18: warning: unused variable 'setFlag'

надо какой-то инклуд добавить? или что?


Название: Re: Ханойские башни
Отправлено: pastor от Январь 14, 2010, 22:14
Код
C++ (Qt)
QGraphicsRectItem *item = new QGraphicsRectItem();
item->setFlag(QGraphicsItem::ItemIsMovable, true);
item->setRect(QRectF(-100.0, -100.0, 50.0, 50.0));
 
scene->addItem(item);


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 14, 2010, 22:30
хмм всеравно вот такие ошибки выдает

Код:
item->setFlag(QGraphicsItem::ItemIsMovable, true);
src\mainwindowimpl.cpp:10: error: invalid use of undefined type `struct QGraphicsRectItem'
../../../QtCreator/qt/include/QtGui/../../src/gui/graphicsview/qgraphicsscene.h:70: error: forward declaration of `struct QGraphicsRectItem'

Код:
item->setFlag(QGraphicsItem::ItemIsMovable, true);
src\mainwindowimpl.cpp:11: error: invalid use of undefined type `struct QGraphicsRectItem'
../../../QtCreator/qt/include/QtGui/../../src/gui/graphicsview/qgraphicsscene.h:70: error: forward declaration of `struct QGraphicsRectItem'
src\mainwindowimpl.cpp:11: error: incomplete type `QGraphicsItem' used in nested name specifier

Код:
item->setRect(QRectF(-100.0, -100.0, 50.0, 50.0));
src\mainwindowimpl.cpp:12: error: invalid use of undefined type `struct QGraphicsRectItem'
../../../QtCreator/qt/include/QtGui/../../src/gui/graphicsview/qgraphicsscene.h:70: error: forward declaration of `struct QGraphicsRectItem'

Код:
scene->addItem(item);
src\mainwindowimpl.cpp:13: error: no matching function for call to `QGraphicsScene::addItem(QGraphicsRectItem*&)'


Название: Re: Ханойские башни
Отправлено: Dendy от Январь 14, 2010, 22:33
#include <QGraphicsRectItem>


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 20, 2010, 19:26
Помогло ) спасибо.
Теперь может кто-нибудь подсказать какой командой или образом можно сделать так, чтобы при переносе мышкой кольца, когда отпускаешь оно смотрело находится-ли оно на линии башни и если да то перерисовывало по определенным координатам, а если отпускаешь и оно не на линии то возвращало в исходное(до начала перетаскивания) место.

Сами координаты думаю легко будет определить в каких случаях где перерисовывать, но каким образом сделать чтобы оно проверяло на линии оно или нет, и если да то на какой.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 20, 2010, 19:57
и еще вопросик
   
Код:
QGraphicsRectItem *item[15] = new QGraphicsRectItem();
как правильно массив из 15 таких элементов обьявить? этот вариант не получился


Название: Re: Ханойские башни
Отправлено: Авварон от Январь 20, 2010, 20:55
QGraphicsRectItem *item[15];
for (int i = 0; i < 15; i++) {
    item = new QGraphicsRectItem();
}


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 20, 2010, 21:03
пасиб, сработало.
А насчет того чтобы проверять на линии или нет, не знаете команды случаем или способа?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 20, 2010, 21:05
А насчет того чтобы проверять на линии или нет, не знаете команды случаем или способа?

используй
Код:
bool QGraphicsItem::collidesWithItem ( const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const   [virtual]


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 20, 2010, 23:01
а можно как-то отключить автоцентрирование сцены? а то подберу координаты для одного квадрата, начну для другого подбирать, а первый уже в совсем другом месте.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 20, 2010, 23:05
а точно, говорилиже задать координаты ее точно ) помогло.


Название: Re: Ханойские башни
Отправлено: pastor от Январь 21, 2010, 00:43
QGraphicsRectItem *item[15];
for (int i = 0; i < 15; i++) {
    item = new QGraphicsRectItem();
}

А еще лучше:

Код
C++ (Qt)
QList<QGraphicsRectItem *>items;
 
for (int i = 0; i < 15; i++) {
   items.append(new QGraphicsRectItem());
}

И незабыть освободить потом память


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 21, 2010, 12:43
Цитировать
QList<QGraphicsRectItem *>items;
 
for (int i = 0; i < 15; i++) {
    items.append(new QGraphicsRectItem());
}

хмм а какие преймущества у такого способа?
и как сделать чтобы память освобождало?


Название: Re: Ханойские башни
Отправлено: Авварон от Январь 21, 2010, 13:36
хм, я точно помню что писал item, специально еще возвращался в начало строки... По ходу глюки...

освобождать память qDeleteAll(items);


Название: Re: Ханойские башни
Отправлено: pastor от Январь 21, 2010, 13:37
хмм а какие преймущества у такого способа?

Даже с точки зрения безопасности (есть контроль выхода за пределы). Ну и конечно это Qt-way ;)

и как сделать чтобы память освобождало?

Код
C++ (Qt)
qDeleteAll(list.begin(), list.end());
list.clear();


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 21, 2010, 16:47
хмм вот мой код

Код:
QGraphicsScene * scene = new QGraphicsScene;
scene->setSceneRect(QRectF(-500,-500,1000,1000));
graphicsView->setScene(scene);

QList<QGraphicsRectItem *>item;
  int i;
for (int i = 1; i < 16; i++) {
    item.append(new QGraphicsRectItem());
}

item[1]->setRect(QRectF(-410, 210.0, 160.0, 50.0));
scene->addItem(item[1]);
эта часть отдельно вроде работает, а вот когда пытаюсь сделать вот
Код:
	for (i=3;i< 16;i++)
{item[i]->setRect(QRectF(-410.0+i*5, 160.0, 160.0-10*i, 50.0));
scene->addItem(item[i]);}
то ошибки в самой программе не находит но когда запускаю само приложение выдает ошибку виндовса типа....эээ  отправлять не отправлять отчет ) и соответственно не работает, не подскажите где ошибка у меня?


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 21, 2010, 16:58
все нашел... хмм почемуто i<15 надо было делать, хотя создавал вроде i<16


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 21, 2010, 17:01
и еще проблемка
Код:
qDeleteAll(item.begin(), item.end());
item.clear();
это хорошо, но как мне сделать попроще чтобы оно не удаляло сразу, и из-за этого не отоброжалось, а после того как окно закрываю


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 21, 2010, 17:59
да гмм и можно подробней описать плиз это
Код:
bool QGraphicsItem::collidesWithItem ( const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const   [virtual]
на примере, если мой квадрат item[1] соприкоснется с line_2 , как организовать с помощью этого кода, и где писать что дальше делаться будет.


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 22, 2010, 02:58
и еще проблемка
Код:
qDeleteAll(item.begin(), item.end());
item.clear();
это хорошо, но как мне сделать попроще чтобы оно не удаляло сразу, и из-за этого не отоброжалось, а после того как окно закрываю
дак перехватите closeEvent и там удаляйте

да гмм и можно подробней описать плиз это
Код:
bool QGraphicsItem::collidesWithItem ( const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const   [virtual]
на примере, если мой квадрат item[1] соприкоснется с line_2 , как организовать с помощью этого кода, и где писать что дальше делаться будет.
вызываете item[1]->collidesWithItem(line_2). Если там истина, значит пересечение есть и делаете то что нужно в случае пересечения (ну наверно вам нужно проверить можно ли класть кольцо на этот штырь и перебросить кольцо).


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 22, 2010, 11:39
ясно, спасибо )


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 15:23
хмм, может дело в том что у меня линия создана в дизайнере, вобщем выдает ошибку
Код:
 if(item[15]->collidesWithItem(line_3))
        {item[15]->setRect(QRectF(-225.0, 160.0, 190.0, 25.0));}

C:/MAKSIM 100117/hanoi/src/mainwindowimpl.cpp:31: error: no matching function for call to 'QGraphicsRectItem::collidesWithItem(QFrame*&)'

в такомже варианте
Код:
        if(item[15]->collidesWithItem(item[13]))
        {item[15]->setRect(QRectF(-225.0, 160.0, 190.0, 25.0));}

программа запускается, однако при наведении на 13 квадрат координаты никак не меняются, подскажите плз в чем ошибка.

Еще можете подсказать естьли  вариант колайда, только такого если ни с чем не соприкоснулось.

и ммм    :-\  можно пример как перехватить closeEvent


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 16:19
Немного понял, оноже сразу программу выполняет и уже не смотрит на условия после выполнения, но как мне сделать чтобы оно после выполнения программы проверяло условия после перемещения?

и насчет линийже как сделать чтобы работали с колайдом созданные в дизайнере линии? или прийдеться создавать объекты сцены линии?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 24, 2010, 18:06
Немного понял, оноже сразу программу выполняет и уже не смотрит на условия после выполнения, но как мне сделать чтобы оно после выполнения программы проверяло условия после перемещения?
э, что? вы хотите чтобы после того как ваша программа завершилась, она что то делала еще? так не бывает

и насчет линийже как сделать чтобы работали с колайдом созданные в дизайнере линии? или прийдеться создавать объекты сцены линии?
надо создать графикайтемы конечно чтобы с ними можно было коллизии проверять

По поводу closeEvent и его перехвата.
В том классе, у объектов которого хотите перехватить closeEvent просто определите протектед метод
void closeEvent ( QCloseEvent * event ) 
и в нем делайте что вам нужно


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 18:18
эмм ну я так понял чтобы срабатывало надо сигнал и слот соеденить в коде, теперь думаю как обозначить сигнал item-а(или чего лучше?) что он отпущен, ну а слотом функцию в this которая перерисовывает как надо, это вроде понятно.
Хотя... я пока назначил сигнал на одну из кнопок,
Код:
connect(pushButton,SIGNAL(clicked()),this,SLOT(Move()));
когда нажимается, а слот соответсвенно функцию
Код:
void MainWindowImpl::Move()
{
    item[15]->setRect(QRectF(-225.0, 160.0, 190.0, 25.0));
}

проблема вот в чем первый раз когда я кнопку нажимаю оно выполняется, однако потом, когда я переместившийся квадрат передвину на другое место и снова нажимаю кнопку, то он уже не перемещается. В чем моя ошибка?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 24, 2010, 19:37

проблема вот в чем первый раз когда я кнопку нажимаю оно выполняется, однако потом, когда я переместившийся квадрат передвину на другое место и снова нажимаю кнопку, то он уже не перемещается. В чем моя ошибка?

может выложите минимально компилируемый исходник?


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 19:41
Код:
#include "mainwindowimpl.h"
#include <QGraphicsRectItem>
//
QList<QGraphicsRectItem *>item;
MainWindowImpl::MainWindowImpl( QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
setupUi(this);
QGraphicsScene * scene = new QGraphicsScene;
scene->setSceneRect(QRectF(-500,-500,1000,1000));
graphicsView->setScene(scene);

        QGraphicsLineItem *line[6];
  int i;
for (int i = 1; i < 17; i++) {
    item.append(new QGraphicsRectItem());
}

        for (i = 1; i < 7; i++) {
    line[i] = new QGraphicsLineItem();
        }

        line[1]->setLine(-330, 260, -330.0, -170.0);line[2]->setLine(-450, 260, -210.0, 260.0);
        line[3]->setLine(-60, 260, -60.0, -170.0);line[4]->setLine(-180, 260, 60.0, 260.0);
        line[5]->setLine(240, 260, 240.0, -170.0);line[6]->setLine(90, 260, 360.0, 260.0);
        for(i=1;i<7;i++)
        {scene->addItem(line[i]);}

        for (i=1;i<16;i++)
{item[i]->setRect(QRectF(-425.0+5*i, 260.0-25*i, 190.0-10*i, 25.0));
scene->addItem(item[i]);}

item[15]->setFlag(QGraphicsItem::ItemIsMovable, true);
        item[13]->setFlag(QGraphicsItem::ItemIsMovable, true);

        if(item[15]->collidesWithItem(item[13]))
        {item[15]->setRect(QRectF(-225.0, 160.0, 190.0, 25.0));}
        connect(pushButton,SIGNAL(clicked()),this,SLOT(Move()));
        connect(pushButton_2,SIGNAL(clicked()),this,SLOT(Delete()));

}


void MainWindowImpl::Move()
{
    item[15]->setRect(QRectF(-225.0, 160.0, 190.0, 25.0));
}

void MainWindowImpl::Delete()
{        qDeleteAll(item.begin(), item.end());
    item.clear();
}

ммм вот? )


Название: Re: Ханойские башни
Отправлено: BRE от Январь 24, 2010, 19:50
Компилябельный пример, это архив со всеми необходимыми файлами для сборки проекта.  ;)

Массивы нумеруются с 0, а не с 1.
Ниже происходит выход за пределы массива line.
Код:
        QGraphicsLineItem *line[6];
  int i;

        for (i = 1; i < 7; i++) {
    line[i] = new QGraphicsLineItem();
        }


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 20:52
аа вот )
я нумерую с 1, прост потомучто удобней так как-то )

почему выходит? там написано <7 тоесть когда i=7 то оно не делает еше раз, да и ошибкаб была у меня, уже сталкивался с такой,а ее нет.


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 24, 2010, 20:54
аа вот )
я нумерую с 1, прост потомучто удобней так как-то )

почему выходит? там написано <7 тоесть когда i=7 то оно не делает еше раз, да и ошибкаб была у меня, уже сталкивался с такой,а ее нет.
вы создаете массив из 6 элементов. Их индексы: 0, 1, 2, 3, 4, 5. Элемента с индексом 6 здесь нет, но вы к нему обращаетесь.


Название: Re: Ханойские башни
Отправлено: BRE от Январь 24, 2010, 20:55
почему выходит? там написано <7 тоесть когда i=7 то оно не делает еше раз, да и ошибкаб была у меня, уже сталкивался с такой,а ее нет.
Инструкция QGraphicsLineItem *line[6]; определяет массив из 6 указателей на QGraphicsLineItem.
Индексация идет от 0, т.е. валидные индексы 0, 1, 2, 3, 4, 5. А ты последний элемент заносишь по индексу 6!

BlackTass уже ответил...  :)


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 20:55
аа, да-да вы правы, странно правда почемуто все 6 линий нормально рисовало почемуто


Название: Re: Ханойские башни
Отправлено: BRE от Январь 24, 2010, 20:56
аа, да-да вы правы, странно правда почемуто все 6 линий нормально рисовало почемуто
В релизе думаю начались бы проблемы.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 21:46
хмм, так можете что-то в качестве сигнала посоветовать?)  чтобы запускал функцию, после того как я отпускаю перетаскиваемый кубик


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 24, 2010, 21:52
такого сигнала нет. Переопределяйте
Код:
void QGraphicsItem::dropEvent ( QGraphicsSceneDragDropEvent * event )   [virtual protected]


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 22:17
хмм (
а примера простого нет? а то не совсем пойму как сделать  ::)


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 24, 2010, 22:25
Наследуетесь от нужного класса айтемов (видимо QGraphicsRectItem), там переопределяете этот метод, в нем пишите то что вам нужно (впринципе можно сделать свой сигнал и там его испускать). На сцену складываете экземпляры уже не QGraphicsRectItem, а своего класса.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 23:08
Сори всеравно не пойму как это сделать, я придумал другой способ
Создаю таймер
Код:
#include <QTimer>
QTimer *timer = new QTimer();

Код:
timer->start(1000);
        connect(timer, SIGNAL(timeout()), this, SLOT(Move()));

И далее в функции Move проверяю не колайдятсяли и запускаю таймер заново
Код:
void MainWindowImpl::Move()
{......
timer->start(1000);
}


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 23:12
хмм... хотя не очень получается способ ( во время перетаскивания тоже работает и убирает от курсора.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 24, 2010, 23:20
хотяяя можно делать проверку не перетаскивается объект и если да то ничего с ним не делать, подскажите естьли у ректитемов проверка на то перетаскиваютьсяли в данный момент или нет?

item[15]->isUnderMouse()  пока нашел, но не лучший вариант конечно, isActive и isSelected почему-то не действуют как я ожидаю от них, перетаскиваю я или нет на результат не влияет


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 01:02
хмм когда перетаскиваю на другую башню, то после проверки на колайд и назначения новых координат, появляется совсем не там где я ожидаю... оно даже зависит от того в каком месте на линии соприкасается., разве координаты задают не точное расположение объектов, а только смещение какоето?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 02:37
Решение с таймером мягко говоря как путь из Москвы в Питер через Новосиб.
Код
C++ (Qt)
class MyGraphicsRectItem : public QGraphicsRectItem
{
   Q_OBJECT
signals:
   void itemDropped();
protected:
   void dropEvent (QGraphicsSceneDragDropEvent *event)
   {
       emit itemDropped();
   }
};
 
При добавлении айтемов на сцену вместо экземпляров QGraphicsRectItem кидаете экземпляры этого класса.
Коннектите к сигналу itemDropped слот, в котором уже проверяете на коллизии (чтобы получить объект который испустил сигнал вызовите sender() в слоте).

хмм когда перетаскиваю на другую башню, то после проверки на колайд и назначения новых координат, появляется совсем не там где я ожидаю... оно даже зависит от того в каком месте на линии соприкасается., разве координаты задают не точное расположение объектов, а только смещение какоето?
Опять же тут можно гадать веками что у вас не так.
Выложите минимально компилируемую версию, так будет проще.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 14:05
хмм ну я тогда вначале переделаю как вы говорите, чтобы при отпускании проверяло ) а то у меня с таймером там уже 5-6 уровневые ифы  пришлось делать.

когда пытаюсь сделать это, делаю инклуд в h-нике(пытался и в мэйнвиндова и отдельно для майграфикректитема создавал)
Код:
#include <QGraphicsRectItem>
и код данный вами, но оно выдает ошибки (

build\moc_MyGraphicsRectItem.cpp:41: error: `staticMetaObject' is not a member of `QGraphicsRectItem'
build\moc_MyGraphicsRectItem.cpp: In member function `virtual void* MyGraphicsRectItem::qt_metacast(const char*)':
build\moc_MyGraphicsRectItem.cpp:55: error: `qt_metacast' is not a member of `QGraphicsRectItem'
build\moc_MyGraphicsRectItem.cpp: In member function `virtual int MyGraphicsRectItem::qt_metacall(QMetaObject::Call, int, void**)':
build\moc_MyGraphicsRectItem.cpp:60: error: `qt_metacall' is not a member of `QGraphicsRectItem'
build\moc_MyGraphicsRectItem.cpp: In member function `void MyGraphicsRectItem::itemDropped()':
build\moc_MyGraphicsRectItem.cpp:75: error: no matching function for call to `QMetaObject::activate(MyGraphicsRectItem* const, const QMetaObject*, int, int)'
../../../QtCreator/qt/include/QtCore/../../src/corelib/kernel/qobjectdefs.h:311: note: candidates are: static void QMetaObject::activate(QObject*, int, void**)
../../../QtCreator/qt/include/QtCore/../../src/corelib/kernel/qobjectdefs.h:312: note:                 static void QMetaObject::activate(QObject*, int, int, void**)
../../../QtCreator/qt/include/QtCore/../../src/corelib/kernel/qobjectdefs.h:313: note:                 static void QMetaObject::activate(QObject*, const QMetaObject*, int, void**)
../../../QtCreator/qt/include/QtCore/../../src/corelib/kernel/qobjectdefs.h:314: note:                 static void QMetaObject::activate(QObject*, const QMetaObject*, int, int, void**)


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 14:11
да, точно, совсем забыл что графикайтем не куобжект. Добавьте еще наследование от QObject'а.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 14:47
ммм можно еще подсказать насчет конекта?
Код:
connect(item[15],SIGNAL(itemDropped()),sender(),Move());

src\mainwindowimpl.cpp:41: error: invalid use of void expression

в чем ошибся?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 14:50
Код:
connect(item[15],SIGNAL(itemDropped()),sender(),SLOT(Move()));
только я не понял зачем вы здесь сендер используете. Или это происходит в слоте, который связан с сигналом объекта у которого и есть данный метод Move() ?


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 14:54
А со скобкой ошибся ( плохо без QT Creator-а а инет плохой здесь не скачать.

да нет, то я так пробовал думал может нужно так чтобы ошибки не было, вобщем конечный вариант такой?

Код:
		for(int i=1;i<16;i++){
        connect(item[i],SIGNAL(itemDropped()),this,SLOT(Move()));}


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 15:17
хмм,
сделал так
Код:
connect(item[15],SIGNAL(itemDropped()),this,SLOT(Move()));

функция

Код:
void MainWindowImpl::Move()
{
item[13]->setRect(QRectF(-225.0+n1, 160.0, 190.0, 25.0));
}

и 13ый никак не реагирует

выкладываю исходник еще если что.


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 15:20
вечером гляну, если раньше никто не отпишется


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 15:25
Ясн, мож за это время и сам разберусь. Спасиб за то чем уже помог )


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 19:40
попробуйте заменить дропЕвент на
Код
C++ (Qt)
   bool sceneEvent (QEvent *event)
   {
       if (event->type() == QEvent::UngrabMouse)
           emit itemDropped();
       return QGraphicsRectItem::sceneEvent(event);
   }
 


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 20:04
Заработало ) пасиб
и вот та проблема что и с таймером у меня возникла при перерисовке
Код:
connect(item[15],SIGNAL(itemDropped()),this,SLOT(Move()));

Код:
void MainWindowImpl::Move()
{
if(item[15]->collidesWithItem(line[3])){
item[15]->setRect(QRectF(-225.0+5*15, 260.0-25*n2, 190.0-10*15, 25.0));
}
if(item[15]->collidesWithItem(line[5])){
item[15]->setRect(QRectF(155.0+5*15, 260.0-25*n3, 190.0-10*15, 25.0));}
}

вот если функцию мув сделать такой то оно перерисовывает не так как еслибы только создался итем и зависит даже от того в каком месте пересечет линию


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 20:59
замените setRect() на setPos() и все будет ок


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 21:22
Ура пашет ) надеюсь больше проблем не будет, осталось кроме механизма только автопрохождение сделать.

Единственное что хочу пока спросить, как сделать чтобы окно с сообщением выскакивало, типа "вы выйграли", "ошибка"?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 25, 2010, 21:52
QMessageBox::warning()
ну и посмотрите там статик методы у QMessageBox


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 25, 2010, 23:29
эмм а sender() это QObject, как мне написать что это ректитем на самом деле в функции?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 26, 2010, 00:08
qobject_cast<MyGraphicsRectItem *>(sender())


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 26, 2010, 00:17
хмм всеравно ошибки выдает после того как вначале функции
Код:
qobject_cast<MyGraphicsRectItem *>(sender())
сделал.

src\mainwindowimpl.cpp:53: error: 'class QObject' has no member named 'collidesWithItem'
src\mainwindowimpl.cpp:54: error: 'class QObject' has no member named 'setPos'

пытался так
Код:
MyGraphicsRectItem *items=qobject_cast<MyGraphicsRectItem *>(sender());

тогда ошибка далее src\mainwindowimpl.cpp:58: error: `items' cannot be used as a function


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 26, 2010, 09:12
где-то накосячили, так как вот такое работает и выводит позиции
Код:
void MainWindowImpl::Move()
{
    MyGraphicsRectItem *currItem = qobject_cast<MyGraphicsRectItem *>(sender());
    qDebug() << currItem->pos();
//...
}


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 26, 2010, 10:23
дебаг у меня тоже пашет ) а вот функции типа сетсайз и проверку на колайд делать не хочет


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 26, 2010, 14:18
тогда ошибка далее src\mainwindowimpl.cpp:58: error: `items' cannot be used as a function
ну вот это явно вы что-то не так делаете. покажите эту строку.
Если отрабатывает pos(), значит тип корректно привелся к айтему, дело не в дебаге.


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 26, 2010, 16:51
Код:
void MainWindowImpl::Move()
{
MyGraphicsRectItem *items=qobject_cast<MyGraphicsRectItem *>(sender());
items()->setPos(-75+5*15, 350.0-25*(n1-1));

}

разобрался уже )
Код:
items->setPos(-75+5*15, 350.0-25*(n1-1));

items без скобок надо было


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 27, 2010, 19:46
ммм а как мне задержку попроще сделать? вроде функции flood в С++ кажется

надо чтото вроде этого?
Код:
QTimer::singleShot(1000, this, SLOT(Caption()));

ток что в слоте использовать?


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 28, 2010, 10:47
какую задержку? для чего именно она вам нужна?


Название: Re: Ханойские башни
Отправлено: Nekron от Январь 28, 2010, 21:38
Ну мне автопрохождение еще надо сделать ) и я хочу чтобы оно переставило кольцо, сделало задержку и дальше.


Название: Re: Ханойские башни
Отправлено: BlackTass от Январь 28, 2010, 21:55
Ну таймер вполне для этого подойдет. Делаете метод, который делает один ход и в конце делает singleShot, который зацикливаете на этот же метод


Название: Re: Ханойские башни
Отправлено: Nekron от Февраль 05, 2010, 20:23
Ураааа ) все наконец доделал и сдал эту курсовую.
Большое спасибо всем за помощь )) особенно товарищу BlackTass