目录
由于视图控件的拖放逻辑比较难,需要同时子类化视图和模型,那么对于小数据而言,不如使用便捷类。因此,决定对多段曲线展示器进行更新升级。顺便练习一下如何使用便捷类。
在v1.0的基础上进行修改创作,形成v1.1版本。首先打开开发页面。
对布局控件进行下更新,将视图改为便捷类。
在主程序进行升级标注:
/*
2023.12.17
将视图改为便捷类
*/
#include <QtGui/QApplication>
#include <QTextCodec>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 文本编码规定
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF8"));
MainWindow w;
w.show();
return a.exec();
}
对程序内涉及到模型-视图的内容进行注释或删除。先让程序能跑起来。
接下来在构造函数里先测试QListWidget的功能。首先看看如何添加item
new QListWidgetItem("aaa",ui->listWidget);
new QListWidgetItem("bbb",ui->listWidget);
new QListWidgetItem("ccc",ui->listWidget);
运行后的效果:
看来用这种方式就可以添加item了。那么怎么获取item值。
qDebug()<<ui->listWidget->count();
可以获取到当前有3行数据。
for(int i = 0; i<ui->listWidget->count(); i++)
qDebug()<<ui->listWidget->item(i)->data(Qt::DisplayRole).toString();
可以访问各行数据。
由于拖放多项可能顺序有误,还需要能拖动各个item,需要设置:
ui->listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
ui->listWidget->setDragEnabled(true);
ui->listWidget->viewport()->setAcceptDrops(true);
ui->listWidget->setDropIndicatorShown(true);
ui->listWidget->setDragDropMode(QAbstractItemView::InternalMove);
下面试试效果:
鼠标可以调整各个item的顺序,完美。
接下来研究下怎么打开文件。先实现action。
// 打开文件
void MainWindow::on_actionOpen_triggered()
{
// 指定多个文件
QStringList files = QFileDialog::getOpenFileNames(this,"Open files",workDir,"*.txt");
if(files.isEmpty())
return;
// 循环读取文件
for(int i = 0; i<files.count(); i++)
{
MagBase mag;
mag.readFile(files.at(i));
magList<<mag;
startTimeIndex<<0;
endTimeIndex<<mag.count-1;
}
// 循环写入列表
ui->listWidget->clear();
for(int i = 0; i<files.count(); i++)
{
new QListWidgetItem(files.at(i),ui->listWidget);
}
// 更新工作路径
QFileInfo info(files.last());
workDir = info.absolutePath()+"//";
// 选中第1行
ui->listWidget->setCurrentItem(ui->listWidget->item(0));
on_listWidget_clicked(ui->listWidget->currentIndex());
// 绘图
plot();
}
文件的打开实现了指定路径,打开数据,写入列表,更新路径,选中当前行并指定点击回调等逻辑。这些都可以写到open函数中,然后在激活拖放。
由于不仅仅是写入列表这么简单,在一个也为了不用专门子类化,可以把拖放写在main windows里。
在main window的头文件中重写两个函数:
protected:
void dragEnterEvent(QDragEnterEvent *);
void dropEvent(QDropEvent *);
具体实现方法为:
/* 拖动进入事件 */
void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
// 数据中包含url 则接收动作 否则忽略该事件
if(e->mimeData()->hasUrls())
e->acceptProposedAction();
else
e->ignore();
}
/* 拖动放下事件 */
void MainWindow::dropEvent(QDropEvent *e)
{
const QMimeData *mimeData = e->mimeData();
if(mimeData->hasUrls())
{
QList<QUrl> urlList = mimeData->urls();
QStringList files;
for(int i = 0; i<urlList.count(); i++)
{
QString inFile = urlList.at(i).toLocalFile();
inFile.replace("\\","/");
files<<inFile;
}
openFiles(files);
}
}
代码解析:第1个就是为了获取拖放信息,第2个在获取信息后,需要将urlList转换为QStringList,而且在转换前需要将\全部置换为/
最后调用open函数即可。
测试后,程序正确。