zoukankan      html  css  js  c++  java
  • QT5 拖拽事件

    我们在编写文本编辑器的时候,可能会希望其具有支持这种功能,将文件直接拖入文本编辑器打开。

    使用方法

    • 1.包含头文件
    //拖拽事件
    #include <QDragEnterEvent>
    //放下事件
    #include <QDropEvent>
    
    • 2.在类中加上如下声明
      • 1)void dragEnterEvent(QDragEnterEvent *event);
      • 2)void dropEvent(QDropEvent *event);
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        //复写”拖拽事件“函数
        void dragEnterEvent(QDragEnterEvent *event);
    
        //复写”放下事件“函数
        void dropEvent(QDropEvent *event);
    };
    
    • 3.在类的构造函数中设置接受drop事件
    //拖拽事件, 也就是可以直接将要打开的文件, 拖入此窗口打开
    this->setAcceptDrops(true);
    
    • 4.复写“拖拽事件”函数
    void MainWindow::dragEnterEvent(QDragEnterEvent *event)
    {
        if(event->mimeData()->hasUrls())
        {
            event->acceptProposedAction();
        }
        else
        {
            event->ignore();
        }
    }
    
    • 5.复写“放下事件”函数
    void MainWindow::dropEvent(QDropEvent *event)
    {
        const QMimeData *mimeData = event->mimeData();
    
        if(!mimeData->hasUrls())
        {
            return;
        }
    
        QList<QUrl> urlList = mimeData->urls();
    
        //如果同时拖入了多个资源,只选择一个
        QString fileName = urlList.at(0).toLocalFile();
        if(fileName.isEmpty())
        {
            return;
        }
    
        //打开拖入的文件
        QFile file(fileName);
        if(!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::information(this, "错误", file.errorString(), QMessageBox::Ok);
            return;
        }
    
        //将文件内容放入文本框
        QByteArray ba;
        ba = file.readAll();
        ui->textEdit->setText(QString(ba));
    }
    
    • 6.效果
      • 1)拖入mainWindow,也就是我的主窗口


        这表示是成功的,注意这里拖入的是mainWindow
      • 2)拖入textEdit和mainWindow的重叠区域


        这里显然是失败的,为什么会这样?
    • 7.分析

    查看官方帮助文档,关于setAcceptDrops(bool on)有如下说明:
    acceptDrops : bool
    This property holds whether drop events are enabled for this widget
    Setting this property to true announces to the system that this widget may be able to accept drop events.
    If the widget is the desktop (windowType() == Qt::Desktop), this may fail if another application is using the desktop; you can call acceptDrops() to test if this occurs.
    Warning: Do not modify this property in a drag and drop event handler.
    By default, this property is false.
    Access functions:
    bool acceptDrops() const
    void setAcceptDrops(bool on)

    关键的地方是:设置这个属性有可能会失败
    我的窗口里面有一个textEdit,textEdit也能接受drop事件,怀疑可能是这个原因

    • 8.解决
      我在构造函数将textEdit接受drop事件禁用掉
    //禁用textEdit的拖拽事件
    ui->textEdit->setAcceptDrops(false);
    


    至此,能愉快的拖放了。

    • 9.总结
    1.这里只是打开了mainWindow接受drop事件,而没有打开textEdit接受drop事件。
    2.就drop事件来说,默认是关闭的。
    3.为什么textEdit的drop事件也被开启了,导致mainWindow的drop事件没触发。
    4.怀疑“事件过滤器”在mainWindow/widget等窗口控件上,设置接受某个事件后,窗口上的子控件也能接受该事件。
    5.如果想只是触发mainWindow的事件,而子部件不需要,则需要将子部件该事件禁用掉。
    
  • 相关阅读:
    C 语言模拟 C++ 的多态(利用指针函数)
    emplace_back 使用零拷贝添加元素验证
    const char*和char* 以及string的相互转化.md
    strcpy和memcpy用法(待完善测试用例)
    结构体的比较
    引用在汇编层次上面的解释
    信息安全管理33_防病毒管理策略
    信息安全管理32_通用安全管理checklist
    信息安全管理31_信息安全符合性管理策略
    信息安全管理30_运行管理checklist
  • 原文地址:https://www.cnblogs.com/risesource/p/11873877.html
Copyright © 2011-2022 走看看