0

我是 qt 的初学者,我做我的第一个项目。我遇到了一个问题。

我将一些编辑行放在滚动区域中。所有这些编辑文本都应该包含文件的路径。为了使这个应用程序更加用户友好,我决定实现拖放。通过这种方式,用户可以从他们的资源管理器中获取一个文件并将其拖放到行编辑中,该行将填充文件的路径。

我的问题是:当我尝试删除时,我的鼠标经过的所有编辑行都将填充文件的路径。如果我通过 else if 更改 if 语句,它是我的鼠标传递的第一个编辑行,它将被填充,但不是我的鼠标在下降时所在的编辑行。

这里的代码:



    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);
        }
    }

我不太明白的另一点是:

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

当我将鼠标放在编辑线上并停留在上面时,我会在控制台中看到两条消息...我希望在鼠标进入时看到第一个消息,而当我的鼠标离开时看到第二个消息。

提前感谢您的帮助。

4

2 回答 2

0

根据您对我的评论的回答,我会尽力帮助您。我不是 Qt 的专家,所以我可能是错的,但由于还没有答案,我会尝试给出一个答案。

我试图重现您的代码和第二个问题:

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

MainWindow如果和 lineEdits 都管理拖放(setAcceptDrops(true)) ,我有相同的行为。我认为您在输入时“输入” MainWindow,然后在输入时“离开”,lineEdit因为它自己管理拖放。

如果您设置:

    ui->lineEdit->setAcceptDrops(false);

然后你就不再“离开”了。

对于第一部分

如果我尝试重现您的代码,则说明该underMouse()功能有问题。也许你的问题来自这里?如果我实现自己的underMouse(),那么一切都很好。

我希望有更好的 Qt 知识的其他人会来帮助你。

于 2021-03-17T18:06:35.347 回答
0

好的,我找到了解决方案。我真的不喜欢它,因为我觉得它不是很干净,但它确实有效。如果其他人有更清洁的解决方案,我愿意接受。我把我的解决方案放在这里。也许这可以帮助将来的某人。我最终没有使用 drop 方法,但我使用了一个 eventFilter,它让我可以更好地管理事件。

<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>

我现在不管理过滤器中的返回,但想法就在这里。

于 2021-03-17T23:08:56.763 回答