I am having issues moving a QGraphicItem in a custom QGraphicView class. What I would like to be able to to do is select the item by a left mouse click and then move it to where I've done a right mouse click.
I stongly suspect that my problem is that QGraphicsItem::setPos() requires the coordinates to be in parent coordinates, and I'm unsure which for of QMouseEvent::*Pos() to use, and how to convert it to parent coordinates.
Screens shots of what is happening, versus what I what follow the code.
main.cpp: (simple main here, standard test harness)
#include "QtTest.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtTest w;
w.show();
return a.exec();
}
QtTest.h: (This defines the main application window)
#pragma once
#include <QtWidgets/QMainWindow>
class QGraphicsView;
class QGraphicsScene;
class QGraphicsItem;
class QMouseEvent;
class QtTest : public QMainWindow
{
Q_OBJECT
public:
QtTest(QWidget *parent = Q_NULLPTR);
private:
QGraphicsView* m_gv;
QGraphicsScene* m_pScene;
void setupUI();
};
QtTest.cpp: (implementation of the main application window)
#include "QtTest.h"
#include "testGV.h"
#include <QVariant>
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QMainWindow>
#include <QMouseEvent>
#include <QWidget>
QtTest::QtTest(QWidget *parent): QMainWindow(parent)
{
setupUI();
}
void QtTest::setupUI()
{
QWidget *centralWidget;
if (objectName().isEmpty())
setObjectName("QtTestClass");
resize(600, 400);
centralWidget = new QWidget(this);
centralWidget->setObjectName("centralWidget");
m_gv = new testGV(centralWidget);
m_gv->setObjectName("graphicsView");
m_gv->setGeometry(QRect(100, 10, 441, 331));
setCentralWidget(centralWidget);
}
testGV.h: (definition of custom widget)
#pragma once
#include <QGraphicsView>
#include <QGraphicsItem>
class testGV : public QGraphicsView
{
Q_OBJECT
public:
testGV(QWidget* parent);
protected:
void mousePressEvent(QMouseEvent*);
private:
QGraphicsScene* m_pScene;
QGraphicsItem* m_pItem;
void createScene();
};
testGV.cpp: (implementation of custom widget)
#include "testGV.h"
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QMouseEvent>
testGV::testGV(QWidget* parent) : QGraphicsView(parent)
{
createScene();
}
void testGV::createScene()
{
m_pScene = new QGraphicsScene();
m_pScene->addRect(QRect(30, 30, 150, 150), QPen(Qt::black), QBrush(Qt::black, Qt::NoBrush));
QGraphicsEllipseItem* pTemp = m_pScene->addEllipse(QRect(0, 0, 15, 15), QPen(Qt::black), QBrush(Qt::red, Qt::SolidPattern));
pTemp->setFlag(QGraphicsItem::ItemIsMovable);
pTemp->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
setScene(m_pScene);
}
void testGV::mousePressEvent(QMouseEvent* pEvent)
{
if (pEvent->button() == 1) // left button click
{
m_pItem = itemAt(pEvent->pos());
}
else if (pEvent->button() == 2) // right button click
{
m_pItem->setPos(pEvent->pos());
m_pScene->update();
}
}
The image on the left is the initial display, when I right click on the red dot and then click in the square at about where the black dot is I get the image on the right. What I'm after is the red dot moving to where I clicked.
The cause of the problem is that the QMouseEvent has the position information in the coordinates of the view but the item uses the coordinates of the scene. The solution in that case is to map the coordinates of the view to the coordinates of the scene:
void testGV::mousePressEvent(QMouseEvent* pEvent)
{
if (pEvent->button() == Qt::LeftButton)
m_pItem = itemAt(pEvent->pos());
else if (pEvent->button() == Qt::RightButton)
if(m_pItem)
m_pItem->setPos(mapToScene(pEvent->pos()));
}
But even so there is a problem, the position for your items is with respect to the topLeft so the displacement will have an error, if you want to avoid that deviation then you must consider the position of the left click:
void testGV::mousePressEvent(QMouseEvent* pEvent)
{
if (pEvent->button() == Qt::LeftButton){
m_pItem = itemAt(pEvent->pos());
m_pItem->setData(0, mapToScene(pEvent->pos()));
}
else if (pEvent->button() == Qt::RightButton)
if(m_pItem){
QPointF p = m_pItem->data(0).toPointF();
QPointF sp = mapToScene(pEvent->pos());
m_pItem->setPos(m_pItem->pos() + sp - p);
m_pItem->setData(0, sp);
}
}
Note: When a pointer is created it points to any memory location so that can cause problems so I recommend initializing it to nullptr and also checking if the pointer is valid:
testGV::testGV(QWidget* parent) : QGraphicsView(parent), m_pItem(nullptr)
{
createScene();
}
Related
The following toy problem show two tabs, each tab contains a QGridLayout, which has a ScrollArea on one of the cells, which in turn contains a customized QLabel (MyLabel). When the user moves his mouse on the customzied QLabel, a tooltip shows up for several seconds.
test.pro
QT += core gui widgets
CONFIG += c++17
CONFIG += debug
QMAKE_CXXFLAGS += -std=c++17
SOURCES += \
test.cpp
QMAKE_CLEAN += $$TARGET Makefile
HEADERS += \
mywidget.h
test.cpp
#include "mywidget.h"
#include <QApplication>
#include <QtGui>
#include <QtCore>
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyMainWindow myMainWindow;
myMainWindow.show();
return a.exec();
}
mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QDebug>
#include <QWidget>
#include <QMdiArea>
#include <QMainWindow>
#include <QScrollArea>
#include <QLabel>
#include <QGridLayout>
#include <QMouseEvent>
#include <QToolTip>
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel(QWidget *parent=nullptr, const QString &name="")
: QLabel(parent), m_name(name)
{
resize(1800, 1200);
setMouseTracking(true);
}
private:
void mouseMoveEvent(QMouseEvent *ev) override {
QToolTip::showText(
ev->globalPosition().toPoint()
, m_name + ": " + QString::number(ev->pos().x()) + ", " + QString::number(ev->pos().y())
);
QLabel::mouseMoveEvent(ev);
}
private:
QString m_name;
};
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget* parent = nullptr, const QString &name="")
: QWidget(parent), m_name(name)
{
setWindowTitle(name);
m_gridLayout = new QGridLayout(this);
this->setLayout(m_gridLayout);
// layout col 1
m_gridLayout->addWidget(new QLabel("smaller label", this), 0, 0);
// layout col 2
m_scrollArea = new QScrollArea(this);
MyLabel *label = new MyLabel(this, m_name);
m_scrollArea->setWidget(label);
m_gridLayout->addWidget(m_scrollArea, 0, 1);
}
private:
QString m_name;
QGridLayout *m_gridLayout;
QScrollArea *m_scrollArea;
};
class MyMainWindow : public QMainWindow
{
Q_OBJECT
public:
MyMainWindow(QWidget* parent = nullptr)
: QMainWindow(parent)
{
m_mdiArea = new QMdiArea(this);
this->setCentralWidget(m_mdiArea);
MyWidget *myWidget1 = new MyWidget(this, "widget 1");
m_mdiArea->addSubWindow(myWidget1);
MyWidget *myWidget2 = new MyWidget(this, "widget 2");
m_mdiArea->addSubWindow(myWidget2);
m_mdiArea->setViewMode(QMdiArea::ViewMode::TabbedView);
}
private:
QMdiArea *m_mdiArea;
};
#endif // MYWIDGET_H
Here are two problems that I am struggling with:
How can I show the tooltip without moving my mouse when I toggle between those two tabs by Ctrl+Tab? In my real-world problem, I use the tooltip show information about data at the mouse point.
Is it possible show some legends on the top-right corner of the viewport of the QScollArea, regardless of the positions of the scoll bars? I am trying with paintEvent, but had difficulties get the position adjusting according to scoll bars.
Cursor postion can be retrieved by using QCursor::pos(), so both problems can be sovlved by using QCuros::pos() in paintEvent. I was confused by the fact paintEvent does not directly provide cursor position, as mouseMoveEvent does.
I'm trying to draw a line using the mouseEvent functions from my QGraphicsScene, when i press the mouse button and move over the scene, the line begin from the top left [0,0] when it should start at the point where i pressed the mouse button, but when i release and do that again the line is drawn normally, what is the reason for this behavior and how to resolve it ?
Here is the full code:
Scene.h:
#ifndef SCENE_H
#define SCENE_H
#include <QGraphicsScene>
#include <QGraphicsLineItem>
#include <QGraphicsSceneMouseEvent>
class Scene : public QGraphicsScene
{
public:
Scene();
private:
QGraphicsLineItem* line;
QPointF startPoint;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
};
#endif // SCENE_H
Scene.cpp:
#include "Scene.h"
Scene::Scene() : startPoint(0,0)
{
line = new QGraphicsLineItem();
this->addItem(line);
}
void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
startPoint = event->scenePos();
}
void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
qreal x = event->scenePos().x();
qreal y = event->scenePos().y();
line->setLine(startPoint.x(),startPoint.y(),x,y);
}
Main:
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include "Scene.h"
int main(int argc,char* argv[])
{
QApplication app(argc,argv);
Scene scene;
QGraphicsView view(&scene);
view.setMinimumSize(800,600);
view.setAlignment(Qt::AlignLeft|Qt::AlignTop);
view.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view.show();
return app.exec();
}
The problem is caused because the QGraphicsScene object is not initialized with a bounding box. In the constructor use
Scene::Scene() : QGraphicsScene(0, 0, 400, 400), startPoint(0,0)
(for example), and it will work as expected.
If you do not do this, at the time of the first click the scene coordinates will relocate so that the starting coordinates of your line (say, (x0, y0)) will be the scene coordinates of the top-left corner. So if you move a mouse just a bit, e.g. to (x0+1,y0), the actual scene coordinates will become (2*x0+1,2*y0).
Also, it is good practice to call the parent class' event handlers at the end of your overloaded ones.
Finally, this can be helpful:
https://www.walletfox.com/course/qgraphicsitemruntimedrawing.php
I am learning Qt for fun. And I got a question:
How could I drag and drop the QLabel in Qt among two different windows?
Here is what I have so far:
As you can tell from the .gif(which does not want to become downloaded and visible here for some reasons, but if you click on the link to it, you can clearly see it) provided above right now there are two main problems:
I can not move the QLabel outside of the window (and hence am not able to register the drag and drop event).
The label is flashing for some reasons when I am moving it.
Here is the relevant part of the implementation from the .gif:
#ifndef DRAGGERP_H
#define DRAGGERP_H
#include <QLabel>
#include <QApplication>
#include <QMouseEvent>
#include <QPoint>
class DraggerP : public QLabel
{
QPoint offset;
QPoint startingPosition;
public:
DraggerP(QWidget* parent = nullptr) : QLabel(parent){ }
protected:
void enterEvent(QEvent* event) override
{
QApplication::setOverrideCursor(Qt::PointingHandCursor);
}
void leaveEvent(QEvent* event) override
{
QApplication::restoreOverrideCursor();
}
void mousePressEvent(QMouseEvent* event) override
{
startingPosition = pos();
offset = QPoint(
event->pos().x() - pos().x() + 0.5*width(),
event->pos().y() - pos().y() + 0.5*height()
);
}
void mouseMoveEvent(QMouseEvent* event) override
{
move(event->pos() + offset);
}
void mouseReleaseEvent(QMouseEvent* event) override
{
move(startingPosition);
}
};
#endif // DRAGGERP_H
This is the extension of the QLabel I am using to create the drag and drop effect.
I do not need the whole solution, at least an idea of how to accomplish this and what am I doing wrong here.
Here is a pretty good example and I used it as a starting point.
That strange movement that the QLabel suffers is because the position of the QLabel now depends on the layout, the job of the layout is to establish the position of the widgets depending on the policies you establish.
The solution is not to implement those actions in the QLabel but in the MainWindow as I show below:
#include <QApplication>
#include <QLabel>
#include <QMainWindow>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QTime>
#include <QDrag>
#include <QMimeData>
#include <QMouseEvent>
class MainWindow: public QMainWindow {
QScrollArea scrollArea;
QWidget contentWidget;
QVBoxLayout lay;
public:
MainWindow(QWidget* parent=nullptr): QMainWindow(parent){
qsrand((uint) QTime::currentTime().msec());
setCentralWidget(&scrollArea);
scrollArea.setWidget(&contentWidget);
contentWidget.setLayout(&lay);
scrollArea.setWidgetResizable(true);
for(int i=0; i< 20; i++){
QLabel *label = new QLabel(QString("label %1").arg(i));
QPalette pal = label->palette();
pal.setColor(QPalette::Background, QColor(10 +qrand() % 240, 10 +qrand() % 240, 10 +qrand() % 240));
label->setAutoFillBackground(true);
label->setPalette(pal);
lay.addWidget(label);
}
setAcceptDrops(true);
}
protected:
void mousePressEvent(QMouseEvent *event){
QMainWindow::mousePressEvent(event);
QWidget *child = childAt(event->pos());
if(qobject_cast<QLabel *>(child))
createDrag(event->pos(), child);
}
void dropEvent(QDropEvent *event){
QByteArray byteArray = event->mimeData()->data("Label");
QWidget * widget = *reinterpret_cast<QWidget**>(byteArray.data());
QLabel * new_label = qobject_cast<QLabel *>(widget);
QWidget *current_children = childAt(event->pos());
QLabel * current_label = qobject_cast<QLabel*>(current_children);
int index = 0;
if(new_label){
if(current_label)
index = lay.indexOf(current_label);
else{
index = 0;
QLayoutItem *item = lay.itemAt(index);
while(item->widget()->pos().y() < event->pos().y() && item)
item = lay.itemAt(index++);
}
lay.insertWidget(index, new_label);
}
}
private:
void createDrag(const QPoint &pos, QWidget *widget){
if(widget == Q_NULLPTR)
return;
QByteArray byteArray(reinterpret_cast<char*>(&widget),sizeof(QWidget*));
QDrag *drag = new QDrag(this);
QMimeData * mimeData = new QMimeData;
mimeData->setData("Label",byteArray);
drag->setMimeData(mimeData);
QPoint globalPos = mapToGlobal(pos);
QPoint p = widget->mapFromGlobal(globalPos);
drag->setHotSpot(p);
drag->setPixmap(widget->grab());
drag->exec(Qt::CopyAction | Qt::MoveAction);
}
protected:
void dragEnterEvent(QDragEnterEvent *event){
if(event->mimeData()->hasFormat("Label"))
event->acceptProposedAction();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w1;
MainWindow w2;
w1.show();
w2.show();
return a.exec();
}
I'm trying to create a simple frame in Qt with a tick and some text. I made two new label implementations because I wanted the labels to dynamically fill all the available space but when I resize the window the sizes are off, as shown by the qDebug output, which represents the size of the image label:
Resized: 244 , 244 <-- Window first created
Resized: 305 , 305 <-- Window maximized
Resized: 135 , 135 <-- Window restored to original size
As you can see, when the window is restored to its original size the image is not. The last size should be 244, 244.
The code which describes the behaviour of the two widgets is the following:
"widgets.h":
/*
* This file includes many custom widgets.
*/
#ifndef APOCRYPHA_WIDGETS
#define APOCRYPHA_WIDGETS
#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QPixmap>
#include <QResizeEvent>
#include <QPaintEvent>
class AutoTextLabel : public QLabel {
Q_OBJECT
public:
explicit AutoTextLabel(QWidget* parent);
AutoTextLabel(QWidget* parent, QString text);
protected:
void resizeEvent(QResizeEvent* event) override;
private:
QTimer* resizeTimer;
private slots:
void onResizeEnd();
};
class AutoImageLabel : public QLabel {
Q_OBJECT
public:
explicit AutoImageLabel(QWidget* parent);
AutoImageLabel(QWidget* parent, const QPixmap& pixmap);
void setFillOrientation(int orientation);
QSize sizeHint() const override;
public slots:
void setPixmap(const QPixmap &newPix);
void resizeEvent(QResizeEvent* event) override;
protected:
// void paintEvent(QPaintEvent* event) override;
private:
int fillOrientation;
int widthForHeight(int h) const;
int heightForWidth(int w) const override;
QPixmap scaledPixmap() const;
QPixmap labelPixmap;
};
#endif //APOCRYPHA_WIDGETS
"widgets.cpp":
/*
* This file includes many custom widgets.
*/
#include "widgets.h"
#include <QPainter>
#include <QDebug>
AutoTextLabel::AutoTextLabel(QWidget *parent, QString text) : QLabel(text, parent){
// Enable antialiasing
QFont aaFont(font());
aaFont.setStyleStrategy(QFont::PreferAntialias);
setFont(aaFont);
// This timer is used to fire a slot when a window is resized
resizeTimer = new QTimer();
resizeTimer->setSingleShot(true);
connect(resizeTimer, SIGNAL(timeout()), SLOT(onResizeEnd()));
}
AutoTextLabel::AutoTextLabel(QWidget *parent) : AutoTextLabel(parent, "") {}
void AutoTextLabel::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
// Only fire when 25ms have passed since the last resize.
resizeTimer->start(25);
}
void AutoTextLabel::onResizeEnd() {
QFont updatedFont(font());
// Resize Text
if (!text().isEmpty()){
int fontSize = 1;
updatedFont.setPixelSize(fontSize);
QRect boundingRectangle;
// Update bounding rectangle
if (wordWrap())
boundingRectangle = QFontMetrics(updatedFont).boundingRect(contentsRect(), Qt::TextWordWrap, text());
else
boundingRectangle = QFontMetrics(updatedFont).boundingRect(text());
while (boundingRectangle.height() <= contentsRect().height()) {
fontSize++;
updatedFont.setPixelSize(fontSize);
// Update bounding rectangle
if (wordWrap())
boundingRectangle = QFontMetrics(updatedFont).boundingRect(contentsRect(), Qt::TextWordWrap, text());
else
boundingRectangle = QFontMetrics(updatedFont).boundingRect(text());
}
updatedFont.setPixelSize(fontSize - 1);
setFont(updatedFont);
}
}
/* Auto Image Label */
AutoImageLabel::AutoImageLabel(QWidget *parent, const QPixmap &pixmap) : QLabel(parent) {
setMinimumSize(1, 1);
setScaledContents(false);
setPixmap(pixmap);
}
AutoImageLabel::AutoImageLabel(QWidget *parent) : QLabel(parent) {
setScaledContents(false);
}
void AutoImageLabel::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
if(!labelPixmap.isNull())
QLabel::setPixmap(scaledPixmap());
qDebug() << "Resized: " << scaledPixmap().width() << ", " << scaledPixmap().height();
}
int AutoImageLabel::widthForHeight(int h) const {
return labelPixmap.isNull() ? width() : (labelPixmap.width() * h) / labelPixmap.height();
}
int AutoImageLabel::heightForWidth(int w) const {
return labelPixmap.isNull() ? height() : (labelPixmap.height() * w) / labelPixmap.width();
}
void AutoImageLabel::setFillOrientation(int orientation) {
this->fillOrientation = orientation;
}
QSize AutoImageLabel::sizeHint() const {
if (fillOrientation == Qt::Horizontal)
return QSize(width(), heightForWidth(width()));
else
return QSize(widthForHeight(height()), height());
}
QPixmap AutoImageLabel::scaledPixmap() const {
return labelPixmap.scaled(sizeHint(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
void AutoImageLabel::setPixmap(const QPixmap &newPix) {
labelPixmap = newPix;
QLabel::setPixmap(scaledPixmap());
}
"other_frames.h":
//
// Created by Riccardo on 18/09/2017.
//
#ifndef APOCRYPHA_OTHER_FRAMES_H
#define APOCRYPHA_OTHER_FRAMES_H
#include <QFrame>
#include <QLabel>
#include <QGridLayout>
#include <QWidget>
#include <QResizeEvent>
#include <QPixmap>
#include <QTimer>
#include "widgets.h"
class ConfirmationFrame : public QFrame {
Q_OBJECT
public:
explicit ConfirmationFrame(QWidget* parent);
ConfirmationFrame(QWidget* parent, const QString& text);
private:
QGridLayout* layout;
AutoImageLabel* imageLabel;
AutoTextLabel* textLabel;
};
#endif //APOCRYPHA_OTHER_FRAMES_H
"other_frames.cpp":
//
// Created by Riccardo on 18/09/2017.
//
#include "other_frames.h"
#include <QDebug>
ConfirmationFrame::ConfirmationFrame(QWidget* parent, const QString &text) : QFrame(parent) {
textLabel = new AutoTextLabel(this, text);
QPixmap pix(":/images/check-tick.png");
imageLabel = new AutoImageLabel(this, pix);
textLabel->setAlignment(Qt::AlignCenter);
imageLabel->setAlignment(Qt::AlignCenter);
textLabel->setWordWrap(true);
// Green Background
setStyleSheet("background-color: rgba(106, 242, 94, 1);");
layout = new QGridLayout();
layout->setSpacing(0);
layout->setContentsMargins(32, 32, 32, 32);
layout->setRowStretch(0, 1);
layout->setRowStretch(1, 1);
layout->addWidget(imageLabel, 0, 1);
layout->addWidget(textLabel, 1, 1);
setLayout(layout);
}
ConfirmationFrame::ConfirmationFrame(QWidget *parent) : ConfirmationFrame(parent, "") {
}
"window_main.h":
#ifndef WINDOW_MAIN_H
#define WINDOW_MAIN_H
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QGridLayout>
#include <QFrame>
#include <QScreen>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
QFrame *mainFrame;
void center(QScreen* screen);
void autoSetSize(QScreen* screen);
private:
void createMenu();
// Components
QGridLayout *mainLayout;
QMenuBar *menuBar;
QMenu *fileMenu;
};
#endif // WINDOW_MAIN
"window_main.cpp":
#include "window_main.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
mainFrame = new QFrame();
mainLayout = new QGridLayout();
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
createMenu();
mainFrame->setStyleSheet("background-color: red;");
mainFrame->setLayout(mainLayout);
setCentralWidget(mainFrame);
}
void MainWindow::createMenu(){
menuBar = new QMenuBar;
fileMenu = new QMenu(tr("&File"), this);
menuBar->addMenu(fileMenu);
setMenuBar(menuBar);
}
void MainWindow::center(QScreen *screen) {
QSize size = screen->availableSize();
int x = size.width() / 2 - width() / 2;
int y = size.height() / 2 - height() / 2;
move(x, y);
}
void MainWindow::autoSetSize(QScreen *screen) {
QSize screenSize = screen->availableSize();
// TODO Math.round
setMinimumSize(QSize((int)(screenSize.width() / 1.25), (int)(screenSize.height() / 1.25)));
}
"main.cpp":
#include <QApplication>
#include <iostream>
#include <QFile>
#include "quiz/choice.h"
#include "quiz/question.h"
#include "quiz/quizmaker.h"
#include <QSettings>
#include <QStandardPaths>
#include <QDebug>
#include <src/user_interface/other_frames.h>
#include "user_interface/window_main.h"
#include <QScreen>
#include <QFontDatabase>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
// Set Application Parameters
QCoreApplication::setOrganizationName("Riccardo Fagiolo");
QCoreApplication::setOrganizationDomain("kopharex.me");
QCoreApplication::setApplicationName("Apocrypha");
// Set application font
const int id = QFontDatabase::addApplicationFont(":/fonts/montserrat/Montserrat-Regular.otf");
QString family = QFontDatabase::applicationFontFamilies(id).at(0);
QFont font(family);
font.setStyleStrategy(QFont::PreferAntialias);
a.setFont(font);
// App Settings
QSettings settings;
settings.setValue("data_dir", QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
// Create UI
auto* window = new MainWindow();
ConfirmationFrame* cframe = new ConfirmationFrame(window, "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?");
window->mainFrame->layout()->addWidget(cframe);
window->autoSetSize(a.primaryScreen());
//cframe->updateTextLabel();
window->show();
window->center(a.primaryScreen());
// [...] - Nothing related to user interface.
return a.exec();
}
Here is a screenshot of the current MainWindow and ConfirmationFrame to give you an idea of what i'm trying to accomplish:
Window Screenshot
All comments regarding the code are welcome.
Thanks for any help,
Riccardo
Hello I tried to fix the resizing issue with an hack.
Before starting the timer to resize the text, just reduce its font to a 1 pixel font:
void AutoTextLabel::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
// set a very small font, then start the timer
QFont updatedFont(font());
updatedFont.setPixelSize(1);
setFont(updatedFont);
// Only fire when 25ms have passed since the last resize.
resizeTimer->start(25);
}
Can the effect be acceptable in your opinion?
I have such program: in my Widget I have qpushbuttons, qslider and qgraphicsview. I place qgraphicsscene in qgraphicsview. The problem is that when I click in QGraphicsscene and want to draw a Point, that was clicked, there is a displacement. When I click in center of QGraphicsScene there is not any problems.
if (mouseEvent->button() == Qt::LeftButton)
{
QPointF pos = mouseEvent->scenePos();
addEllipse(pos.x(), pos.y(), 5, 5, QPen(QColor(Qt::green)), QBrush(QColor(Qt::red)));
}
There is a screen too.
So, the question is how to avoid this moving of scene.
In the screen I have clicked in right bottom, but point was drawn in the center
Try this. In my computer it works without displacement
.*h
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QMouseEvent>
class GraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GraphicsScene(QObject *parent = 0);
signals:
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
public slots:
};
#endif // GRAPHICSSCENE_H
*.cpp
#include "graphicsscene.h"
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
GraphicsScene::GraphicsScene(QObject *parent) :
QGraphicsScene(parent)
{
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
qDebug() << "in";
if (mouseEvent->button() == Qt::LeftButton)
{
QPointF pos = mouseEvent->scenePos();
addEllipse(pos.x(), pos.y(), 5, 5, QPen(QColor(Qt::green)), QBrush(QColor(Qt::red)));
}
}
Using
GraphicsScene *scene = new GraphicsScene(this);
ui->graphicsView->setSceneRect(50,50,50,50);//for example
ui->graphicsView->setScene(scene);
ui->graphicsView->show();
view->setSceneRect(0, 0, 640, 480);
has helped me