Просмотр сообщений
|
Страниц: 1 ... 11 12 [13]
|
182
|
Qt / 2D и 3D графика / [Решено] Drag-n-drop QGraphicsItem по одной координате. Сцена "съезжает"
|
: Март 08, 2014, 12:09
|
Добрый день. Мне потребовалось перетаскивать графические элементы не по двум координатам (как это делается по умолчанию, например, в примере chip), а только по одной (двигаю флажки вдоль оси OX). Я перекрыл обработку событий от мыши, в первую очередь, mouseMoveEvent. Вот слегка почищенный код класса Flag (наследника QGraphicsItem): C Flag::Flag(const QString& name, const QColor& color): _name(name), _color(color) { setFlags(ItemIsSelectable | ItemIsMovable); setAcceptHoverEvents(true); } void Flag::paint(QPainter *p, const QStyleOptionGraphicsItem *item, QWidget *widget) { int height = FLAG_HEIGHT; int dX = -FLAG_WIDTH; p->setPen(_color); p->drawLine(0, 1, 0, FLAG_HEIGHT); p->drawLine(0, FLAG_HEIGHT, dX, FLAG_HEIGHT-FLAG_SUBHEIGHT/2); p->drawLine(dX, FLAG_HEIGHT-FLAG_SUBHEIGHT/2, 0, FLAG_HEIGHT-FLAG_SUBHEIGHT); } QRectF Flag::boundingRect() const { return QRectF(-FLAG_WIDTH+1, 2, FLAG_WIDTH, FLAG_HEIGHT); } void Flag::mousePressEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem::mousePressEvent(event); update(); } void Flag::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { // Set new position int newX = event->scenePos().x(); setPos(newX, 1); } void Flag::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem::mouseReleaseEvent(event); }
Вот фрагменты конструктора главного окна: C view = new QGraphicsView(ui->frame); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(view); ui->frame->setLayout(layout); ... QGraphicsScene* scene = new QGraphicsScene; view->setScene(scene); ... Flag* flag = new Flag("magenta", Qt::magenta); view->scene()->addItem(flag); flag = new Flag("black", Qt::black); view->scene()->addItem(flag); flag->setPos(80, 0);
При запуске программы на экране появляются два флажка. Я действительно могу их перетаскивать мышью, но при этом второй флаг "съезжает" в другую сторону. Судя по более сложному примеру, в котором были не только флажки, сдвигается вся сцена. Насколько я могу судить, это связано с тем, что в начале работы у сцены нулевая ширина, по мере вызова setPos для элементов она расширяется, и Qt пытается его отцентровать относительно QGrapgicsView, через который идёт отображение. Я сделал временное решение. В том же конструкторе главного окна сделал принудительную установку размера сцены по виджету: C int w = view->width(); int h = view->height(); scene->setSceneRect(-w/2, -h/2, w, h);
Вроде бы проблема ушла. Но мне интуиция подсказывает, что это костыль, который может к тому же отказать при каком-нибудь "хитром" ресайзе, хотя пока я такого не добился. Есть ли более нормальное решение? Например, как-то отключить эту автоматическую центровку вообще... Проблема проверена на Qt 4.6 и 4.8.4 в Windows и Linux. Спасибо.
|
|
|
183
|
Qt / 2D и 3D графика / Re: Вызов setPos() из paint() графических элементов. Можно?
|
: Январь 02, 2014, 18:57
|
Это не должно работать корректно. если вы не учитывается все моменты, то можете просто свалиться в рекурсию, или же как раз возникнет перекрытие областей (пропадение других итемов) и многое другое. Спасибо, это я и хотел услышать. Не может такого быть что какой-то нужный параметр доступен только в painter. Нужный параметр - это, по большому счёту, ширина отрисовываемой области. (Возможно, в будущем понадобится и высота.) Я ещё немного поэкспериментировал - в принципе, childrenRect() у QGraphicsView возвращает ту же самую ширину, что и viewport() у QPainter. Наверное, я перекрою QGraphicsView::resizeEvent() и буду делать setPos дочерним элементам в нём. (Ну а для драг-н-дропа вызову обновление отдельно.) Это будет корректно?
|
|
|
185
|
Qt / 2D и 3D графика / [Решено]Вызов setPos() из paint() графических элементов. Можно?
|
: Январь 02, 2014, 14:45
|
Добрый день. Допустимо ли вызывать метод QGraphicsItem::setPos из метода paint() наследников этого самого QGraphicsItem? Мне перед отображением элемента надо рассчитать, где он будет выводиться, исходя из масштаба физических величин к ширине отображаемой области. А ширину эту, как я понимаю, я могу взять только из painter-а.
В предыдущей версии своего кода я совсем не пользовался setPos, отрисовывал все элементы в координатах сцены, размеры сцены брал из QPainter::viewport(), и всё, в общем-то, замечательно отрисовывалось. Но теперь мне понадобилось к некоторым элементам добавить перетаскивание, причём перетаскивание не совсем автоматическое - оно разрешено только по одной координате, и при этом надо ещё пересчитывать физическую величину. Первое, что пришлось сделать - это отказаться от координат сцены, иначе проблемы будут уже в boundingRect(). Теперь отрисовку я делаю в координатах самого элемента, а в начале paint() вызываю setPos, рассчитанный исходя из размера отображаемой области. В общем-то, отображение самого элемента работает. Но возникают странные артефакты, например, в процессе расширения окна другие элементы (другого класса, на который действие моего setPos не распространяется) могут исчезать и появляться обратно.
Проблема повторена на Qt 4.6 и 4.8.4, причём мне показалось, что на 4.8.4 глюки были реже, но совсем не исчезли.
Компактный кусок кода, который исчерпывающе иллюстрировал бы проблему, я постараюсь собрать, но сделать это будет нелегко: как-то слишком всё у меня пока размазано. Но может, он и не нужен? Если я действительно пытаюсь сделать то, чего в Qt в принципе делать нельзя - буду искать другие пути. Поэтому буду благодарен, если для начала кто-либо знающий ответит на "теоретический" вопрос, сформулированный в названии темы...
|
|
|
187
|
Qt / Базы данных / Re: Oracle7 драйвер
|
: Февраль 21, 2012, 22:17
|
Есть ещё вариант. Поскольку перекачка данных - операция разовая, можно не геморроиться с драйверами, а сделать структурированный дамп в текстовые файлы, а потом уже его в постгресную базу и грузить. Правда, по производительности этот вариант уступает: полученные файлы могут разрастись до сотен мегабайт, а то и больше. Соответственно, и работать выгрузка/загрузка будет дольше. Зато полная прозрачность.
|
|
|
188
|
Qt / Интернационализация, локализация / Re: Автоматический вызов lrelease
|
: Февраль 21, 2012, 21:40
|
Но там же есть в самом linguist опция "скомпилировать", которая и выдаёт нужный QM.
linguist - это гуёвая программа для _редактирования_ .ts. А у меня задача в данном случае - тупо собрать проект с минимум телодвижений, допустим, из tar.bz2 с исходниками или из svn/hg/git. В общем случае править перевод может один человек, а собирать понадобится другому. Помещать файлы .qm в tar.bz2 и уж тем более коммитить их в svn/hg/git я, естественно, не хочу. Ибо это вторичный продукт по отношению к .ts, да ещё и двоичный. Со всеми вытекающими. Стало быть, надо собирать. Мне показалось, что было бы естественно возложить это на make. Ибо какая разница, что ей вызывать - gcc, uic или lrelrase. Но похоже, что у qmake, которая делает Makefile, на этот счёт другое мнение. P.S. Сейчас ещё раз погуглил - похоже, стандартно проблема не решается, надо добавлять свой скрипт. Авторы кутима так и сделали: http://wiki.qutim.org/ru/how_to_translateвызвать скрипт make.sh из папки translations и собрать перевод в qm файлы Хнык-хнык.
|
|
|
189
|
Qt / Интернационализация, локализация / Автоматический вызов lrelease
|
: Февраль 21, 2012, 15:47
|
Здравствуйте. Попрактиковался я в русификации с помощью linguist. Штука хорошая и надёжная. Только вот что смущает. Если я собираю проект из исходников (qmake / make), всё равно для каждого .ts приходится вручную вызывать lrelease, чтоб получить из него .qm. Программа make этот процесс не автоматизирует. Думал, это у меня проект кривой - при сборке стандартных примеров из Qt та же самая ситуация. Так и должно быть? Если да - непонятно, зачем вообще в файле проекта секция TRANSLATIONS. Да и вообще обидно как-то. Если нет - где могла собака порыться? Поиском на форуме нашёл обсуждение аналогичной проблемы для cmake, но я ей не пользуюсь, полагаюсь на стандартные для Qt средства. До последнего момента мне их хватало.
|
|
|
Страниц: 1 ... 11 12 [13]
|
|
|