0

Im beginner in qt and i do my first project. I am encountering a problem.

I put somes edit line in a scroll area. All of this edit text should countains path to files. To make this app more userfriendly i decided to implement a drag and drop. By this way, users can just take a file from their explorer and drop it to line edit which will be fill with the path of the file.

My problem is: When i try to drop, all edit line where my mouse passed on, will be fill with the path of the file. If i change if statements by else if, its the first edit line that my mouse passed on which will be fill but not the one where my mouse is at the moment of the drop.

here the code:



    void MainWindow::dragEnterEvent(QDragEnterEvent *e)
    {
        e->accept()
    }
     
    void MainWindow::dropEvent(QDropEvent *e)
    {
        foreach (const QUrl &url, e->mimeData()->urls()) {
            QString fileName = StringManagement::getDir(url.toLocalFile());
     
            if(ui->lineEdit->underMouse())
                ui->lineEdit->setText(fileName);
            if(ui->lineEdit_2->underMouse())
                ui->lineEdit_2->setText(fileName);
            if(ui->lineEdit_5->underMouse())
                ui->lineEdit_5->setText(fileName);
            if(ui->lineEdit_9->underMouse())
                ui->lineEdit_9->setText(fileName);
            if(ui->lineEdit_10->underMouse())
                ui->lineEdit_10->setText(fileName);
            if(ui->lineEdit_11->underMouse())
                ui->lineEdit_11->setText(fileName);
        }
    }

On other point that i dont really understand is:

<pre><code>void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
    qInfo() << "enter";
    e->accept();
}
 
 
void MainWindow::dragLeaveEvent(QDragLeaveEvent *e){
    qInfo() << "leave";
    e->accept();
}

when i put my mouse on an edit line and i stay on it, i will see both message in the console... i expected to see the first one when my mouse enter in and the second one when my mouse leave it.

thank you in advance for your helps.

antoine
  • 3
  • 5
  • I don't quite understand what you are trying to do. When you drag-drop multiple files in the scrollArea you want to fill all the lineEdit at the same time or do you just want to drag-drop on file at a time in each lineEdit? – Irisciences Mar 17 '21 at 16:59
  • @Irisciences no. sorry if you didnt understand. i mean, i take one file in my explorer and try to drop it in one line edit. The problem is the drop also fill all lineEdit that my mouse passed by. – antoine Mar 17 '21 at 17:02

2 Answers2

0

Following your answer to my comment I'll try to help you. I'm not an expert at Qt so I may be wrong but since there is no answer yet I'll try to give one.

I tried to reproduce your code and for the second question:

    void MainWindow::dragEnterEvent(QDragEnterEvent *e)
    {
        qInfo() << "enter";
        e->accept();
    }
 
    void MainWindow::dragLeaveEvent(QDragLeaveEvent *e)
    {
        qInfo() << "leave";
        e->accept();
    }

I have the same behaviour if MainWindow and the lineEdits both manage drag and drop (setAcceptDrops(true)). I think that you "enter" when you enter the MainWindow and then "leave" when you enter the lineEdit since it manages itself the drag and drop.

If you set :

    ui->lineEdit->setAcceptDrops(false);

Then you don't "leave" anymore.

For the first part

If I try to reproduce your code, I have a problem with the underMouse() function. Maybe your problem comes from here? If I implement my own underMouse() then everything is fine.

I hope someone else with better Qt knowledge will come to your help.

Irisciences
  • 308
  • 2
  • 9
  • Thank you. You helped me to understand. I found a solution. Im still little bit confuse about how work this events but i can continue without thinking about it (for now ^^) – antoine Mar 17 '21 at 22:55
0

Ok i find a solution. I dont really like it because i dont find it really clean but that works. If others have cleaner solution im open to it. I put my solution here. Maybe that could help someone in the future. I finaly didn't use drop methode but i used an eventFilter which give me the posibility to have a better management of events.

<pre><code>MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    {
    this->data = DataModel::GetInstance();
    ui->setupUi(this);
    setAcceptDrops(true);
    //ui->lineEdit->dragEnabled();
    //ui->lineEdit->setAcceptDrops();
    installEventFilter(this);
    ui->lineEdit->installEventFilter(this);
    ui->lineEdit_2->installEventFilter(this);
    ui->lineEdit_5->installEventFilter(this);
    ui->lineEdit_9->installEventFilter(this);
    ui->lineEdit_10->installEventFilter(this);
    ui->lineEdit_11->installEventFilter(this);

    }

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *e)
  {
      qInfo() << "enter";
      e->accept();
  }

bool MainWindow::eventFilter(QObject* obj, QEvent* event){


    if(event->type() == QEvent::DragEnter){
        if(obj == ui->lineEdit){
            this->flag = 1;
        }
        else if(obj == ui->lineEdit_2){
            this->flag = 2;
        }
        else if(obj == ui->lineEdit_5){
            this->flag = 3;
        }
        else if(obj == ui->lineEdit_9){
            this->flag = 4;
        }
        else if(obj == ui->lineEdit_10){
            this->flag = 5;
        }
        else if(obj == ui->lineEdit_11){
            this->flag = 6;
        }
         qInfo()<<"flag" <<this->flag;
    }


    if(event->type() == QEvent::Drop){
        qInfo()<< obj;
        QDropEvent *drop = static_cast<QDropEvent *>(event);
        foreach (const QUrl &url, drop->mimeData()->urls()) {
            QString fileName = StringManagement::getDir(url.toLocalFile());
            qInfo()<<"flag drop" <<this->flag;
            if(this->flag == 1){
                ui->lineEdit->setText(fileName);
            }
            else if(this->flag == 2){
                ui->lineEdit_2->setText(fileName);
            }
            else if(this->flag == 3){
                ui->lineEdit_5->setText(fileName);
            }
            else if(this->flag == 4){
                ui->lineEdit_9->setText(fileName);
            }
            else if(this->flag == 5){
                ui->lineEdit_10->setText(fileName);
            }
            else if(this->flag == 6){
                ui->lineEdit_11->setText(fileName);
            }
            return true;


       }


    }

}

</code></pre>

I dont manage return in the filter for now but the idea is here.

antoine
  • 3
  • 5