Essential Qt 第十三章 文件拖放

             这一章,将实现ReadMe程序的最后一个功能,即文件的脱放,想ReadMe这样的编辑器,通过把一个文件拖放至窗体内来实现文件的打开是一个很常见的操作模式,Qt对这一操作做了比较细致的区分,最主要的是通过拖事件dropEnterEvent()以及放事件dragEvent(),除此意外,Qt还提供了dragMoveEvent()和dragLeaveEvent()来应对一些特殊情况或者一些细致的控制,当然大多数时候后两个事件不需要去重新实现。另外需要说明的是这里拖事件,放事件是我取的名字。。。

             在实现拖放功能之前,首先需要做的是在ReadMe构造函数中做些改动,该程序作为编辑用的中心窗体QTextEdit默认是接受拖放操作的,而一般的窗体部件默认不接受拖放的操作的,而我们希望这个程序窗体接受拖放操作,用户在使用这个程序的时候可以把文件拖动到窗体的任意位置来打开,而不是必须拖动到编辑区域,所以在ReadMe函数中需要添加额外的设置

  MainEditWindow->setAcceptDrops(false);//注释1
  setAcceptDrops(true);//注释2

注释1: 这里调用setAcceptDrops()函数来设置编辑窗体QTextEdit不接受拖放事件,前面说过,我们需要整个窗体(程序)来接受拖放

注释2:这个ReadMe程序继承自QMainWindow类,而QMainWindow类默认是不接受拖放事件的,所以这里要设置接受。

             然后就可以开始实现拖放事件了其中拖事件比较简单

void ReadMe::dragEnterEvent(QDragEnterEvent* event)
{
  if(event->mimeData()->hasFormat(tr("text/uri-list")))//注释1
    event->acceptProposedAction();//注释2
}
注释1: 这里调用了拖事件的成员函数mimeData(),这个函数用于返回拖动到窗体上的文件的标识符(类型为QMineData),注意这里的文件可以指硬盘上的任何文件,例如文本文件,视频文件,或者一个硬件驱动文件,换句话说,这个文件相当与linux系统里的“一切皆文件”里的文件。而这个标识符最大的作用就是,我们可以通过标识符(mimeData()函数的返回值)来查看拖入窗体的文件的类型,这里就通过标识符(QMineData类)的成员函数hasFormat()来判断是否是文本文件。这里需要说明的是文件的标识符的标准为MINE类型,为了操作这个类型,Qt定义了类QMimeData,但MINE的相关定义是由国际因特网地址分配委员会定义的,Qt并是标准的制定方

注释2: 表示接受拖事件,这个函数是QDropEvent类的成员函数,Qt中有Drop的事件都会继承自这个类,这个函数表示接受拖事件,而accept()函数表示接受事件,所以这里用这两个函数作用一样,其实QDropEvent类继承子QEvent类,而accept()则是QEvent类的成员函数

              接下来是放事件

void ReadMe::dropEvent(QDropEvent* event)
{
  QList<QUrl> urls = event->mimeData()->urls();//注释1
  if(urls.isEmpty() or (urls.size() > 1))//注释2
    return;
  QString FileName = urls.first().toLocalFile();//注释3
  if(FileName.isEmpty())
    return;
  QFile F(FileName);//注释4
  QTextStream IOs(&F);
  F.open(QIODevice::ReadWrite|QIODevice::Text);
  MainEditWindow->setText(IOs.readAll());
  CurrentFilePath = FileName;
}
注释1: 这里使用了QMineData类的另一个成员函数urls(),这里函数返回拖至窗体上的所有文件的列表,因为选择多个文件,然后拖动至程序的造作很常见,应次要获得拖至窗体的文件名,比如使用列表。关于Qt的容器,和C++的STL差别很小,主要的区别是Qt的容器提供了更多的成员函数来方便操作,不如first()返回地一个元素,last()返回最后一个,成员函数at(index)则用于返回给定索引的元素,等等,各个容器QList,QVector文档上都有详细介绍他们的成员函数的作用,有需要的可以自行查阅,关于容器的使用等由于和C++的STL差别不大所以就不另外单独介绍了。

注释2: 列表urls存放了拖入窗体的所有文件的QUrl列表,由于这是个单文本编辑器,所以这里只接受一个脱放文本

注释3:QUrl类成员函数toLocalFile()用于判断该文件是否属于本地文件,如果是则返回该文件在系统中的绝对路径,如果不是本地文件,则返回一个空的QString

注释4:在确定了拖入的文件符合我们的要求,这里使用前一章关于文件读写的内容将拖放之窗体上的文件在编辑窗体中打开。


                 到这里我们基本完成了ReadMe程序,至少这个时候可以冒充下win系统自带的记事本了。这里说“基本”只的是还有些细节尚不完善,比如这里的拖放事件,中,在拖放时候程序不会判断是否有正在编辑的文本,拖放时也不会询问“尚有未保存的文件,是否需要保持?”,关于这些判断可以参考“新建”和“关闭”里的内容。



在Dockerfile中使用Qt 5.14.1作为编译器,首先需要创建一个基于适合Qt开发的基础镜像。以下是一个基本的Dockerfile示例,用于构建一个基于Ubuntu的镜像,安装Qt 5.14.1和其他依赖: ```dockerfile # 使用官方Ubuntu 20.04作为基础镜像 FROM ubuntu:20.04 # 设置维护者信息 LABEL maintainer="Your Name <your.email@example.com>" # 更新系统并安装必要软件包 RUN apt-get update && \ apt-get install -y \ software-properties-common \ sudo \ # 安装qt5.14.1 libqt5-dev=5.14.1+dfsg-2ubuntu1 \ qttools5-essential \ cmake \ git \ && rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /workdir # 配置sudo免密码登录 RUN echo "root:password" | chpasswd # 暴露端口,例如8080(根据你的应用需求) EXPOSE 8080 # 欢迎消息 USER root RUN echo "Qt 5.14.1 Docker environment is ready." # 更改用户权限以避免不必要的root权限 USER your_username # 添加你的项目或者其他依赖 COPY . /workdir # 进入项目目录并运行构建命令 CMD ["bash", "-c", "cd /workdir && ./configure && make && make install"] ``` 在这个例子中,你需要替换`libqt5-dev=5.14.1+dfsg-2ubuntu1`部分为你实际使用的Qt版本号,同时根据你的项目和编译需求调整其他软件包和命令。`COPY . /workdir`行表示将当前目录的内容复制到Docker容器的工作目录。 使用这个Dockerfile构建镜像: ```sh docker build -t your_image_name . ``` 然后运行镜像: ```sh docker run -it --rm -p 8080:8080 your_image_name ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值