Dropping images in Qt - qt

I am looking to be able to take a QImage and drop it into an editing program such as Paint, for example. I've tried setting the mime data to the current image with the following code, but the data doesn't move correctly. The pixmap is displayed correctly, but the drop never happens. If anyone has any advice, that would be much appreciated! Thanks!
void LCDWidget::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
QImage image = renderFramebuffer(lcdState);
QPixmap mymap = QPixmap::fromImage(image);
mimeData->setImageData(image);
drag->setMimeData(mimeData);
drag->setHotSpot(e->pos());
drag->setPixmap(mymap);
drag->exec(Qt::CopyAction | Qt::MoveAction);
e->accept();
} else {
e->ignore();
}
}

I eventually figured this out with the following code. The solution is to copy the image to a local file, and then use the path to the file as the copy data.
void LCDWidget::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
QImage image = getImage();
QPixmap mymap = QPixmap::fromImage(image);
QString path = QDir::tempPath() + randomString(5) + QStringLiteral(".png");
image.save(path, "PNG", 0);
mimeData->setImageData(image);
mimeData->setUrls(QList<QUrl>() << QUrl::fromLocalFile(path));
drag->setMimeData(mimeData);
drag->setHotSpot(e->pos());
drag->setPixmap(mymap);
drag->exec(Qt::CopyAction | Qt::MoveAction);
e->accept();
} else {
e->ignore();
}
}

Related

Qgraphicsscene troubles to get scenePos() inside a function

I have subclassed a qgraphicsscene and trying to get the mouse coords inside a "normal" function. I only get it working on "mouse involved" function. Sorry I'm amateur programmer.
For exmample here scenePos() works:
void mousePressEvent(QGraphicsSceneMouseEvent *event)
{
// qDebug() << "Custom scene clicked.";
if(event->modifiers() == Qt::ControlModifier) {
if(event->button() == Qt::LeftButton) {
QPointF pos = {event->scenePos().x(), 70};
addChordnueve(pos); // crea 1 item at mouse x e y = 70
// } if(event->modifiers() == Qt::ControlModifier & event->modifiers() == Qt::ShiftModifier) {
qDebug() << "Control!!!";}}
Here it doesn't works at all, but got QCursor::pos() giving "weird" positions:
void preaddExtChord()
{
auto *hellos = scenePos(); //<- It doesn't works
int xplace = QCursor::pos().x()-620;
int yplace = QCursor::pos().y()-380;
QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem("n");
item->setFont(QFont ("omheads", 20));
item->setPos(xplace, yplace);
addItem(item);
}
I searched a lot during months but couldn't find a solution,...
maybe I'm doing a wrong approach, or either there is some easier possibilitie to get the mouse coords inside this type of functions?
Thanks! :-)
If you want to obtain the position with respect to the cursor scene you must first obtain that QGraphicsView is below the cursor (a QGraphicsScene can be part of QGraphicsView), for this we must iterate and verify if it is inside the viewport, then calculate the position with respect to the scene using the mapToScene method of QGraphicsView:
QPoint p = QCursor::pos();
for(QGraphicsView *view: views()){
QWidget *viewport = view->viewport();
QRect vr = viewport->rect();
QPoint vp = viewport->mapFromGlobal(p);
if(vr.contains(vp)){
QPointF sp = view->mapToScene(vp);
QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem("n");
item->setFont(QFont("omheads", 20));
item->setPos(sp);
addItem(item);
}
}

QLabel doesn't display QPixmap

I am trying to display the video frames in a QLabel with the below code but unfortunately, the Video is not displayed on the QLabel. I have inherited QAbstractVideoSurface into CameraFrameGrabber.
bool CameraFrameGrabber::present(const QVideoFrame &frame)
{
qDebug() << __FUNCTION__;
if (frame.isValid()) {
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
if (MainWindow* child = dynamic_cast<MainWindow*>(this)) {
//QGraphicsScene *scene = new QGraphicsScene(this);
//scene->addPixmap(QPixmap::fromImage(image));
//scene->setSceneRect(image.rect());
child->ui->label->setPixmap(QPixmap::fromImage(image));
child->ui->label->update();
//child->ui->graphicsView->setScene(scene);
//child->ui->graphicsView->update();
}
//emit frameAvailable(image);
cloneFrame.unmap();
return true;
}
return false;
}
The Problem is with the VideoFrame format which doesn't match with the QLabel pixmap Formats and also removed dynamic Cast from mainwindow and added a Label in Cameraframegrabber.
QImage outImage = image.convertToFormat(QImage::Format_RGB888);
myLabel->setPixmap(QPixmap::fromImage(outImage));

Drag and Drop QFrame

I've been looking at drag and drop examples and am still puzzled with them. In particular I don't know what to do in mousePressEvent( ) and dropEvent().
I'm following and modifying example which drags and drops QLabel.
Here is what I think mousePressEvent() should look like for QFrame. I tried it and I can see the frame move but I lose it when I drop it.
void SummaryBar::mousePressEvent(QMouseEvent *event)
{
QFrame *child = static_cast<QFrame*>(childAt(event->pos()));
if (!child)
return;
QPixmap pixmap = QPixmap::grabWidget(child);
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << QPoint(event->pos() - child->pos());
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(event->pos() - child->pos());
if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) {
child->close();
} else {
child->show();
}
}
Here is dropEvent(). It obviously does not work... not sure why.
void SummaryBar::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QPixmap pixmap;
QPoint offset;
dataStream >> pixmap >> offset;
QFrame *newFrame = new QFrame(this);
//newFrame->setPixmap(pixmap);
newFrame->move(event->pos() - offset);
newFrame->show();
newFrame->setAttribute(Qt::WA_DeleteOnClose);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
void SummaryBar::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
I would greatly appreciate any help!!

Multiple file insert in QTreewidget using Drag and Drop events

I am working in Qt4.7 on MAC OSx. I want to insert files in QTreewidget using the Drag and Drop events. I want to add multiple files at a time. I am using this:
void MainWindow::dragEnterEvent(QDragEnterEvent * e)
{
if(e->mimeData()->hasUrls())
{
e->acceptProposedAction();
}
}
void MainWindow::dropEvent(QDropEvent * e)
{
QTreeWidgetItem *Items = new QTreeWidgetItem(ui->treeWidget);
foreach(const QUrl &url,e->mimeData()->urls())
{
const QString &filename = url.toLocalFile();
qDebug() << "Dropped file:" << filename;
Items->setText(0,filename);
}
}
Using this, I am able to insert only one file at a time. Is there anyone who can help me out in this issue ? Your help will really appreciate.
Thanks,
Ashish.
The problem is that you create only one tree view item. However you need one per each Url you passed with the mime data:
void MainWindow::dropEvent(QDropEvent *e)
{
foreach(const QUrl &url, e->mimeData()->urls()) {
QString filename = url.toLocalFile();
qDebug() << "Dropped file:" << filename;
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
item->setText(0, filename);
}
}

QTreeview mousePressEvent implementation prevents selection of items

Hello all
I have class that inherited from Qtreeview and I implement simple ( empty ) mousePressEvent function
But whenever I try to do this , the selection of the items in the Qtreeview are disabled , when I remove this function everything is working fine
What im missing here ?
Here Is the code:
void MyTreeWidget::mousePressEvent(QMouseEvent *event)
{
QModelIndex index = this->indexAt(event->pos());
QAbstractItemModel *model = this->model();
QMap<int, QVariant> ItemData = model->itemData(index);
QMap<int, QVariant>::const_iterator i = ItemData.constBegin();
while (i != ItemData.constEnd()) {
QString k = QString::number(i.key());
QString v = i.value().toString();
++i;
}
if (event->button() == Qt::LeftButton) {
QByteArray itemData ;
QString urlTo;
itemData.append(urlTo);
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
drag->setMimeData(mimeData);
Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
if (dropAction == Qt::MoveAction)
{
UT::getInstance()->LogToFile("dropAction");
}
}
QTreeView::mousePressEvent(event);
}
It's because that when you override a method, the original on is not called anymore. You would have to manually call the mousePressEvent method of QTreeView in the method you created.
Here is how to do it:
void YourClass::mousePressEvent ( QMouseEvent * event )
{
QTreeView::mousePressEvent(event);
}
Hope this helps.

Resources