QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器

一、前言

1.在QT学习笔记(六)——①进度条可拖动、点击②有暂停按钮 的视频播放器的基础上构建。
2.因为实现的功能有点多,所以讲解的思路和前几篇不太一样了,先不把UI的设计一股脑儿列出来,而是一个功能一个功能的介绍。
3.实现的功能如下
(1)从本地选择播放源
(2)播放列表;选择过的视频文件列入播放列表(数据库)
(3)双击播放列表中的视频,播放

二、从本地选择播放源

1.UI设计

多加了一个 PushButton,起名为btnAdd.

QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器

; 2.mainwindow.h文件中槽函数的声明

private slots:

   void onBtnAddClicked();

3.槽函数的编写、信号机制


connect(ui->btnAdd,SIGNAL(clicked()),this,SLOT(onBtnAddClicked()));

void MainWindow::onBtnAddClicked()
{

    QString curPath="..\\res";
    QString dlgTitle="选择视频文件";
    QString filter="mp4文件(*.mp4);;所有文件(*.*)";
    QString aFile=QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter);

    if (aFile.isEmpty())
      return;

    QFileInfo   fileInfo(aFile);

    player->setMedia(QUrl::fromLocalFile(aFile));
    player->play();
}

4.”构建个锤子”,运行!

如果不先构建的话,编写代码的时候不认识新加的btnAdd这个控件,所以先”构建个锤子”,没问题了再运行

5.效果

QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
“大家中午好,我是铁矿幼儿nuan小二班的报菜nuan~”

; 三、连接数据库SQLITE 测试工作(真正工作请看“四”)

SQLite是内置的,相当于已经把SQLite加入到DB的环境中了,所以后面我们只需要建立db文件就可以了

1.配置文件修改

在配置文件第一行加入 sql三个字母(其实以前加过了)

QT       += coregui sql

2.UI设计

(1)加入一个tableView,用来显示播放列表
(2)创建个锤子

3.连接数据库 测试工作

首先,先创建一个db文件看看行不行。在mainwindow的构造函数内加入以下代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    qDebug()<<QSqlDatabase::drivers();
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("videoplayer.db");
    db.open();
    db.exec("create table if not exists playlist(id integer primary key autoincrement, name text, url text)");

    db.close();
  }

运行,然后去看能不能生成db文件。db文件可能生成在两个地方,分别是
(1)和项目源码同一个文件夹

QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
(2)在这个项目的配置文件夹(build … MinGW_64_bit Debug)中
QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
创建成功了。然后执行insert、select语句看看能不能成功。
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    qDebug()<<QSqlDatabase::drivers();
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("videoplayer.db");
    db.open();
    QSqlQuery query;
    if(!query.exec("create table if not exists playlist(id integer primary key autoincrement, name text, url text)")){
        qDebug()<<"Error 1 (create error)"<<query.lastError().text();
        return;
    }
    if(!query.exec("insert into playlist(name,url) values('test','urltest')")){
        qDebug()<<"Error 2 (insert error)"<<query.lastError().text();
        return;
    }
    if(!query.exec("select * from playlist")){
        qDebug()<<"Error 3 (select error)"<<query.lastError().text();
        return;
    }
    while(!query.next()){
        qDebug()<<query.value(0).toInt()<<query.value(1).toString()<<
                  query.value(2).toString();
    }
    db.close();
  }

如果失败的话会输出规定的语句,程序输出窗口没有这些输出说明成功了,为了保险起见我们用 DB Browser for SQLite这个软件可视化一下db文件

QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
看insert成功!
QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器

我们希望把数据库里的每一条记录都显示在tableView这个控件上,并且希望只显示它的name字段。
借助一个querymodel,就只需要 3&#x884C;&#x4EE3;&#x7801;!考虑到后面还要用这个model,所以把他写在成员函数里设为全局变量了。

class MainWindow : public QMainWindow
{
private:
    QSqlQueryModel *model;
}

如果这个样子呢,是把整个表弄过来了,虽然很丑,但是我们对于数据库的测试工作已经完成了。

 model = new QSqlQueryModel;
 model->setQuery("select * from playlist");
 ui->tableView->setModel(model);

QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
为什么说以上工作只是测试工作呢?因为我们要实现的是用户在本地文件选中一个mp4文件后,再把文件名插入数据库中,上面insert的只是瞎编的数据,而且把整个表全放进去tableview了,完全不符合项目要求。

四、连接数据库,设置播放列表

1.双击播放列表某一行,开始播放相应视频

声明槽函数

private slots:
void onItemDBCliked(const QModelIndex &index);

连接双击信号


    connect(ui->tableView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(onItemDBCliked(QModelIndex)));

编写槽函数


void MainWindow::onItemDBCliked(const QModelIndex &index){
    qDebug()<<index.row();
    QSqlRecord record = model->record(index.row());

    player->setMedia(QMediaContent(QUrl::fromLocalFile(record.value(2).toString())));
    player->play();
}

2.从本地选择某个文件后,数据库表中新增一行,播放列表也随着刷新
思路是,改写播放本地视频的函数onBtnAddClicked()。选择一个视频以后,立马像数据库中插入一行记录,同时刷新tableView.

这里遇到一个问题是,我们希望tableView只显示视频的名字,而不是把数据库一行记录的所有字段都显示出来,用到的方法是,再定义一个全局变量model2。

model = new QSqlQueryModel;
    model2 = new QSqlQueryModel;
    model->setQuery("select * from playlist");
    model2->setQuery("select name from playlist");
    ui->tableView->setModel(model2);

void MainWindow::onBtnAddClicked()
{

    QString curPath=".\\res";
    QString dlgTitle="选择视频文件";
    QString filter="mp4文件(*.mp4);;所有文件(*.*)";
    QString aFile=QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter);

    if (aFile.isEmpty())
      return;

    QFileInfo   fileInfo(aFile);

    player->setMedia(QUrl::fromLocalFile(aFile));
    player->play();

    QSqlQuery query;

    int index=-1, lastIndex;
    do{
       lastIndex = index;
       index = aFile.indexOf('/',index+1);
    }while(index!=-1);
    QString name = aFile.right(aFile.length()-lastIndex-1);

    QString cmd = QString("insert into playlist(name,url) values('%1','%2')").arg(name).arg(aFile);
    if(!query.exec(cmd)){
          qDebug()<<"Error 2 (insert error)"<<query.lastError().text();
          return;
    }

    model->setQuery("select * from playlist");
    model2->setQuery("select name from playlist");
    ui->tableView->setModel(model2);
}

问题与思考

  1. 如果有的时候你在ui里改了名字,并且也构建了,cpp文件还是不认识这个控件的话,那就再改一个新名字
  2. 用DB Browser fo Sqlite可视化时,运行期间可能会出现这个错误”database is locked Unable to fetch row”。原因是你在这个软件里手动删除了记录,但是没保存,如果再调用insert语句的话,是一种对文件的” &#x5199;&#x5199;&#x4E92;&#x65A5;“。保存一下就好啦。
  3. 关于 &#x4E2D;&#x6587;&#x5B57;&#x7B26;&#x5411;&#x6570;&#x636E;&#x5E93;&#x5B58;&#x50A8;&#x548C;&#x4ECE;&#x6570;&#x636E;&#x5E93;&#x53D6;&#x51FA;的问题。定义数据库table的字段时,将那个字段写为text类型,插入的时候不用管;取出的时候要加一个toString()函数。
  4. 错误:QSqlQuery::value: not positioned on a valid record
    因为我把上一段执行select的语句屏蔽了,query里是空的,所以query.next出错了

    while(!query.next()){
        qDebug()<<query.value(0).toInt()<<query.value(1).toString()<<
                  query.value(2).toString();
    }
  1. 调试程序的时候,如果陷入死循环,点了下面”Stop Running Program”这个小红按钮暂停它以后,如果想要再次编译运行,会提示你.exe 这个程序没有权限打开。
    QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器
    是因为.exe这个程序上次只是终止了,没有被关掉,所以无法再次打开。我们可以WIN10的 &#x4EFB;&#x52A1;&#x7BA1;&#x7406;&#x5668;中找到它,停掉这个任务就可以了。
  2. 目前程序存在一个问题,db.close()以后,后面的数据库操作就进行不了(但不会报错),所以db.open()以后,我一直没有关上它。。。
  3. 数据库的操作如果报出” not positioned on a valid record”说明query这个东西指向的地方不是你认为的地方。比如执行了select以后,结果存放在query中,query指向结果的最后一行的下一行,但是如果你用query.value(0).toInt()这样从query中取结果的话,就要先用一个 query.first()或者 query.next()函数将指针指向结果集的第一行

Original: https://blog.csdn.net/qq_44886213/article/details/120085974
Author: 玛丽莲茼蒿
Title: QT学习笔记(九)—— 实现①从本地选择播放源②连接数据库③带有播放列表的视频播放器

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/817049/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球