How to change drag cursor by dragging in Qt? - c++

I have a widget that accepts drop. The object which is dragged in this example can be any pdf or text file. The requirement is when the dragged object goes inside my widget, the cursor should be changed into another form.
I did some search here, and there is a way to do it setDragCursor, but this function is of QDrag. I did not create the dragged widget myself and from dropEnterEvent and dropMoveEvent I don't know how to change the cursor.
DragWidget.h
#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H
#include <QFrame>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
class DragWidget : public QFrame
{
public:
DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
};
#endif // DRAGWIDGET_H
DragWidget.cpp
#include "dragwidget.h"
#include <QMimeData>
#include <QDebug>
DragWidget::DragWidget(QWidget *parent) : QFrame(parent)
{
setMinimumSize(300, 300);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);
}
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if ( mimeData->hasText() || mimeData->hasFormat( "application/json" ) )
{
qDebug()<<mimeData->text();
}
}
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{
event->acceptProposedAction();
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dragwidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
DragWidget *m_dragWidget=nullptr;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_dragWidget = new DragWidget(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
With the code above, the mouse cursor off course does not change
Do you guys have any idea about this?

Related

How to draw QRubberBand on a QGraphicsView using Mouse?

I have my MainWindow with a GraphicsView on which I want to draw a QRubberBand using MouseEvents. Therefore I created a custom GraphicsView class where I have the MouseEvents, however since I am a beginner, I don't know how to connect everything to the MainWindow.
Here's what I got so far:
mousegraphics.h (custom)
#ifndef MOUSEGRAPHICS_H
#define MOUSEGRAPHICS_H
#include <QGraphicsView>
#include <QWidget>
#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>
class MouseGraphics : public QGraphicsView
{
public:
MouseGraphics(QWidget* parent = nullptr);
public slots:
void mousePressEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e);
private:
QRubberBand* rb = nullptr;
// Coordinates
QPoint origin, dest;
};
#endif // MOUSEGRAPHICS_H
mousegraphics.cpp
#include "mousegraphics.h"
MouseGraphics::MouseGraphics(QWidget* parent) : QGraphicsView(parent)
{
}
void MouseGraphics::mousePressEvent(QMouseEvent *e)
{
origin = e->pos();
if(!rb)
{
rb = new QRubberBand(QRubberBand::Line, this);
}
rb->setGeometry(QRect(origin, QSize()));
rb->show();
}
void MouseGraphics::mouseMoveEvent(QMouseEvent *e)
{
rb->setGeometry(QRect(origin, e->pos()).normalized());
}
void MouseGraphics::mouseReleaseEvent(QMouseEvent *e)
{
rb->hide();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>
#include "mousegraphics.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
you should create one class that inherits from QGraphicsView.
because you need mousePressEvent ,mouseReleaseEvent , mouseMoveEvent of QGraphicsView.
Then in MainWindow, you need one QGraphicsScene object and I create one QGridLayout and with the addWidget function add my QGraphicsView object to MainWindow UI.
So I do this :
In graphicsview.h:
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QObject>
#include <QRubberBand>
class graphicsView: public QGraphicsView
{
public:
graphicsView();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
QRubberBand *rubberBand = nullptr;
QPoint origin;
};
#endif // GRAPHICSVIEW_H
graphicsview.cpp :
#include "graphicsview.h"
#include <QMouseEvent>
#include <QRect>
graphicsView::graphicsView()
{
}
void graphicsView::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
if (!rubberBand)
{
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}
void graphicsView::mouseReleaseEvent(QMouseEvent *event)
{
rubberBand->hide();
}
void graphicsView::mouseMoveEvent(QMouseEvent *event)
{
rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}
In mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
In mainwindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsScene>
#include <QGridLayout>
#include "graphicsview.h"
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGridLayout *gridLayout;
gridLayout = new QGridLayout(centralWidget());
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
auto scene = new QGraphicsScene(this);
graphicsView *_view = new graphicsView();
_view->setScene(scene);
gridLayout->addWidget(_view);
}
MainWindow::~MainWindow()
{
delete ui;
}
The result is this
:

Can't see a widget

I've been trying to create a frame to be shown as a tooltip, but be functionally different. It's got to be shown at a certain point, floating, to be called from a delegate.
Now, if I don't pass a parent it's seen but yeah, it's detached.
And I want it to be windowless.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include <QFrame>
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSize size { 350, 550 };
QPoint topLeft { 550, 550 };
auto* frame = new QFrame(this); // this is a QWidget
frame->setGeometry({ topLeft, size });
frame->show();
frame->activateWindow();
frame->raise();
qInfo() << frame->isVisible(); // returns true
}
MainWindow::~MainWindow()
{
delete ui;
}
Any suggestions?

How can I expand and collapse part of my form with QPropertyAnimation

I want is to show and collapse the groupBox by clicking on the button; so far it works, but i think its not the correct way to do.
The animation looks very bad when the form is expanded and when it is contracted it is a little more normal.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPropertyAnimation>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
QPropertyAnimation *animation;
bool expand=false;
int height;
};
#endif // WIDGET_H
#include "widget.h"
#include "./ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton->setText("expand");
height=this->size().height();
ui->groupBox->setVisible(false);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
if(!expand){
animation=new QPropertyAnimation(this,"size");
animation->setDuration(250);
animation->setEndValue(QSize(this->width(),height));
animation->setEasingCurve(QEasingCurve::InQuad);
animation->start();
ui->groupBox->setVisible(true);
expand=true;
ui->pushButton->setText("Shrink");
}else{
ui->groupBox->setVisible(false);
animation=new QPropertyAnimation(this,"size");
animation->setDuration(250);
animation->setEndValue(QSize(this->width(),(height-ui->groupBox->size().height())));
animation->setEasingCurve(QEasingCurve::InQuad);
animation->start();
expand=false;
ui->pushButton->setText("Expand");
}
}

QT5 Switching between Widgets size problem

I try to switch between two different Widgets in QT5.
The first problem was that my first window was visible in the background of my second window. I solve this with a check in "autoFillBackground". Now i can switch between them, but if i resize them it only resize the Main content.
Both Widgets have a grid layout.
Resize Problem
Im new at QT5, so is there a better way to make a switching between 2 widgets without this problem?
I try it with wMessages = new Messages(); and hide() but then my program crash after going back.
Code:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "messages.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnMessages_clicked();
private:
Ui::MainWindow *ui;
Messages *wMessages;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnMessages_clicked()
{
wMessages = new Messages(this);
wMessages->show();
}
messages.h:
#ifndef MESSAGES_H
#define MESSAGES_H
#include <QWidget>
namespace Ui {
class Messages;
}
class Messages : public QWidget
{
Q_OBJECT
public:
explicit Messages(QWidget *parent = nullptr);
~Messages();
QString NewsGenerator();
private slots:
void on_bBack_clicked();
void on_pushButton_clicked();
private:
Ui::Messages *ui;
};
#endif // MESSAGES_H
messages.cpp:
#include "messages.h"
#include "ui_messages.h"
Messages::Messages(QWidget *parent) :
QWidget(parent),
ui(new Ui::Messages)
{
ui->setupUi(this);
}
Messages::~Messages()
{
delete ui;
}
void Messages::on_bBack_clicked()
{
this->close();
QWidget *parent = this->parentWidget();
parent->show();
}
Edit 1 - working Main Window Button (from G.M.´s answer):
void MainWindow::on_btnMessages_clicked()
{
wPlaner = new Planer();
QMainWindow::setCentralWidget(wPlaner);
}
Update (based on the comments):
The best solution was to use the QStackedWidget to navigate between the views.
Docu: https://doc.qt.io/qt-5/qstackedwidget.html#details
Example-Code for Button:
// return back to first view
void MainWindow::on_btnret_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}

Set connect from another class in QT

I don't get it.
loginview.h
#ifndef LOGINVIEW_H
#define LOGINVIEW_H
#include <QMainWindow>
#include <QDebug>
#include <QPushButton>
class LoginView : public QWidget
{
public:
QWidget *LoginViewSetup(QWidget * wdgMain);
public slots:
virtual void LogInUser();
virtual void CreateUser();
public:
QPushButton *logInBtn;
QPushButton *createBtn;
};
#endif // LOGINVIEW_H
loginview.cpp
#include "loginview.h"
QWidget *LoginView::LoginViewSetup(QWidget * wdgMain)
{
//some code
return wdgCenter;
}
void LoginView::LogInUser()
{
//some code
}
void LoginView::CreateUser()
{
//some code
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <loginview.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QWidget * wdgMain;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
wdgMain = new QWidget(this);
LoginView LoginViewObj;
QWidget *wdgCenter = LoginViewObj.LoginViewSetup(wdgMain);
setCentralWidget( wdgMain );
connect(LoginViewObj.createBtn, SIGNAL (released()), &LoginViewObj, SLOT (CreateUser()));
}
MainWindow::~MainWindow()
{
delete ui;
}
Problem:
QObject::connect: No such slot QWidget::CreateUser() in
../proj/mainwindow.cpp:16
I tried to add Q_OBJECT to the loginview.h and then rebuild project with QMAKE. After that there is no warning about slot, but buttons still not active. Program don't jump to handle of the button in debug mode.
Please, help me to understand what's wrong? I have an object of another class LoginView and I pass this object as a reciever for a slot. Why it passes through my class and searches slot in QWidget?