Solved Problem With QRect and QPainter
-
You need to define steps.
move(pos)
moves the widget directly topos
.
Use aQTimer
and move your rect byx
everyy
msecs. -
@Oumayma To add to @Pl45m4 : you can also use https://doc.qt.io/qt-5/animation-overview.html
-
@jsulm
How can I use a QPropertyAnimation for a Qmenubar and a Qmenu I only find Qbutton examples, thanks. -
@Pl45m4
I'm researching the QTimer but I don't really know how to use it.
The following would be a Qtimer of one second, but I don't know how to use this to make my QRect move after one second has passed:QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);Thanks.
-
For your property animation you can use the example from the documentation
https://doc.qt.io/qt-5/qpropertyanimation.html#details
Animate / Change the geometry of your
QRect
over time.To use the timer approach you'll need a slot, where you manually increase your size, position or whatever you want to change. Just
update()
won't work.Something like:
void MainWindow::AnimateSlot { QPoint currPos = yourRect.topLeft(); // In parent coordinates int moveBy = 1; // Your rect's step size QPoint newPos = QPoint (currPos.x() + moveBy, currPos.y()); yourRect.moveTo(newPos); }
-
@Pl45m4 I don't really know how Slots work, but this is the code that I have tried. It gives me the following error:
QObject::connect: No such slot MainWindow::AnimateSlot(rec)
QObject::connect: (receiver name: 'MainWindow')I will continue to inform myself, but if you see what I'm doing wrong, I would appreciate your help.
void MainWindow::paintEvent(QPaintEvent *e){
Q_UNUSED(e);
QPainter MyPainter(this);
relleno(&MyPainter);
}void MainWindow::relleno(QPainter *paint){
QRect rec = QRect(0, 0, 95, 35);
paint->fillRect(rec,QBrush("#c56c00"));
QTimer timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(AnimateSlot(rec)));
timer->start(1000);
}
void MainWindow::AnimateSlot(QRect rec){
QPoint currPos = rec.topLeft(); // In parent coord/
int moveBy = 180; // Your rect's step size
QPoint newPos = QPoint (currPos.x() + moveBy, currPos.y());
rec.moveTo(newPos);
}Thanks a lot.
-
Hi,
You can't use parameters to slots in the connection call like that one.
You can consider using lambdas.
In any case, you're doing something nasty here, each time paintEvent (and that can happen quite a lot) is called you are creating a new QTimer object.
-
@SGaist I understand thank you very much for the help, I will continue investigating how to solve my problem.
-
@Oumayma I have corrected some of the things mentioned but it still does not work, it does not give me any error but it does nothing.
Modified code:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->textEdit);
ui->menubar->setStyleSheet(" border-style: solid;border-width: 2px;border-color: green;");
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(AnimateSlot()));
timer->start(1000);}
void MainWindow::paintEvent(QPaintEvent *e){
Q_UNUSED(e);
QPainter MyPainter(this);
relleno(&MyPainter,rect());
}void MainWindow::relleno(QPainter *paint,QRect rec){
paint->fillRect(rec,QBrush("#c56c00"));
}
void MainWindow::AnimateSlot(){QPoint currPos = rect().topLeft(); // In parent coord*/ int moveBy = 180; // Your rect's step size QPoint newPos = QPoint (currPos.x() + moveBy, currPos.y()); rect().moveTo(newPos);
}
QRect MainWindow::rect(){
QRect rec;
rec.setRect(0, 0, 95, 35);
return rec;
}thank you very much and sorry for the inconvenience.
-
@Oumayma said in Problem Whit QRec and QPainter:
rect().moveTo(newPos);
What are you expecting from that ?
-
@SGaist I want to be able to see how my rectangle moves from one position to another.
-
@Oumayma said in Problem With QRect and QPainter:
@SGaist I want to be able to see how my rectangle moves from one position to another.
That I understood, but you are not answering my question:
What do you expect from that line, or rather what do you think it does ?
@Oumayma said in Problem With QRect and QPainter:
rect().moveTo(newPos);
-
@SGaist Yes, I'm sorry. I have changed the rect () function, declaring the following in the header file:
QRect rec = QRect (0, 0, 95, 35);
Thanks to that I can use the same rec in the different functions.Now my functions are these:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->textEdit);
ui->menubar->setStyleSheet(" border-style: solid;border-width: 2px;border-color: green;");
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(AnimateSlot()));
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
}
void MainWindow::paintEvent(QPaintEvent *e){
Q_UNUSED(e);
QPainter MyPainter(this);
relleno(&MyPainter);
}void MainWindow::relleno(QPainter *paint){
paint->fillRect(rec,QBrush("#c56c00"));
}
void MainWindow::AnimateSlot(){
QPoint currPos = rec.topLeft();
int moveBy = 95;
QPoint newPos = QPoint (currPos.x() + moveBy, currPos.y());
rec = QRect(0,0,89,35);
rec.moveTo(newPos);
}
With this I have managed to make my rec move until it ends up disappearing, now I am trying to make the rec change in size as it moves and according to the size of the corresponding Qmenu.
I also have to ensure that when I get to the last option of the Qmenu I return to the first option of the Qmenu and so on all the time.
But as you can see in the following image, the rec continues until the end and disappears.
Sorry for the inconvenience and thanks for the help.
-
You are just moving your rectangle every time using the same offset.
You need to add logic to handle the number of elements you have in your menu bar and loop on that.
-
@SGaist Could you guide me or give me some information regarding the handling of items for Qmenubar. Thanks a lot.
-
You know the number of entries of your menu bar, so use it for the loop.