Qt+FFmpeg开发视频播放器笔记(二):界面UI搭建

news2024/9/23 9:31:24

效果图

主要使用无边框窗体搭建,实现窗体的拖动和缩放,播放列表、文件打开等。

主要代码

manwindow设计类

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMutex>
#include "framelesshelper.h"

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_m_closeBtn_clicked();
    void on_m_maxBtn_clicked();
    void on_m_minBtn_clicked();
    void on_m_listBtn_clicked();

    void on_m_openBtn_clicked();

private:
    void InitUI();
    void InitSlots();
    void framelesshelperInit();

private:
    Ui::MainWindow *ui;
    bool isListHid  = true;
    QMap<QString,QString> m_playMap ;
    QMutex m_mapMutex;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::FramelessWindowHint);
    // 适用调色板设置背景色
    QPalette palette(this->palette());
    palette.setColor(QPalette::Window, Qt::gray);   //设置背景黑色
    this->setPalette(palette);
    this->setMouseTracking(true);// 设置鼠标跟踪,不然只会在鼠标按下时才会触发鼠标移动事件
    InitUI();
    framelesshelperInit();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::InitUI()
{
    ui->m_menuBtn->setToolTip("logo");
    ui->m_menuBtn->setAutoRaise(true);
    ui->m_menuBtn->setIcon(QPixmap(":/images/btn_logo.png"));

    ui->m_closeBtn->setToolTip("关闭");
    ui->m_closeBtn->setAutoRaise(true);
    ui->m_closeBtn->setIcon(QPixmap(":/images/btn_close.png"));

    ui->m_minBtn->setToolTip("最小化");
    ui->m_minBtn->setAutoRaise(true);
    ui->m_minBtn->setIcon(QPixmap(":/images/btn_minus.png"));

    ui->m_maxBtn->setToolTip("最大化");
    ui->m_maxBtn->setAutoRaise(true);
    ui->m_maxBtn->setIcon(QPixmap(":/images/btn_normal.png"));

    ui->m_openBtn->setToolTip("打开");
    ui->m_openBtn->setAutoRaise(true);
    ui->m_openBtn->setIcon(QPixmap(":/images/btn_open.png"));

    ui->m_preBtn->setToolTip("上一个");
    ui->m_preBtn->setAutoRaise(true);
    ui->m_preBtn->setIcon(QPixmap(":/images/btn_back.png"));

    ui->m_playBtn->setToolTip("播放");
    ui->m_playBtn->setAutoRaise(true);
    ui->m_playBtn->setIcon(QPixmap(":/images/btn_play.png"));

    ui->m_nextBtn->setToolTip("下一个");
    ui->m_nextBtn->setAutoRaise(true);
    ui->m_nextBtn->setIcon(QPixmap(":/images/btn_next.png"));

    ui->m_setBtn->setToolTip("设置");
    ui->m_setBtn->setAutoRaise(true);
    ui->m_setBtn->setIcon(QPixmap(":/images/btn_set.png"));

    ui->m_listBtn->setToolTip("列表");
    ui->m_listBtn->setAutoRaise(true);
    ui->m_listBtn->setIcon(QPixmap(":/images/btn_list.png"));

    ui->m_volumeBtn->setToolTip("声音");
    ui->m_volumeBtn->setAutoRaise(true);
    ui->m_volumeBtn->setIcon(QPixmap(":/images/btn_voice.png"));

    ui->tableWidget->setStyleSheet("QTableWidget { background-color: gray; } QTableWidget::item:selected {background-color:  gray;}\
         QTableWidget::item:selected:active {background-color: gray;}");
    //ui->tableWidget->horizontalHeader()->hide();
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->setSelectionMode(QAbstractItemView::NoSelection); //被选中后不高亮
    //ui->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    ui->tableWidget->horizontalHeader()->setFont(QFont("Arial", 13));

    // 设置表头不显示网格
    ui->tableWidget->horizontalHeader()->setSectionHidden(0,true);
    ui->tableWidget->verticalHeader()->setSectionHidden(0,true);
    ui->tableWidget->horizontalHeader()->setSectionsClickable(false);//水平表头不可点击
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section {background-color:gray;border: none;} QHeaderView::section { color: blue; }");

    ui->tableWidget->verticalHeader()->hide();
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //选中整行.
    ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); //单行模式.


    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableWidget->setFocusPolicy(Qt::NoFocus); //设置item选中后去掉虚线边框.
    ui->tableWidget->setAcceptDrops(true); //启用拖放事件.
    ui->tableWidget->setColumnCount(1);
    // 也可以设置表头标签,如果你不需要可以省略这一步
    QStringList headers;
    headers << "播放列表";
    ui->tableWidget->setHorizontalHeaderLabels(headers);
    ui->tableWidget->setRowCount(16); // 假设你想要5行
    ui->tableWidget->setColumnWidth(0,220);
}

void MainWindow::InitSlots()
{

}

void MainWindow::on_m_closeBtn_clicked()
{
    close();
}


void MainWindow::on_m_maxBtn_clicked()
{
    showMaximized();
}


void MainWindow::on_m_minBtn_clicked()
{
    showMinimized();
}

void MainWindow::framelesshelperInit()
{
    //this指的是要处理的窗体
    FramelessHelper *pHelper = new FramelessHelper(this);
    pHelper->activateOn(this);  //激活当前窗体
    pHelper->setWidgetMovable(true);  //设置窗体可移动
    pHelper->setWidgetResizable(true);  //设置窗体可缩放
    pHelper->setRubberBandOnMove(false);  //设置橡皮筋效果-可移动
    pHelper->setRubberBandOnResize(true);  //设置橡皮筋效果-可缩放
}

void MainWindow::on_m_listBtn_clicked()
{
    if(isListHid){
        ui->tableWidget->hide();
        isListHid = false;
    }else{
        ui->tableWidget->show();
        isListHid = true;
    }
}

void MainWindow::on_m_openBtn_clicked()
{
    QString strName = QFileDialog::getOpenFileName(this, "选择播放视频~!", "/", "视频 (*.mp4 *.m4v *.mov *.avi *.flv);; 其它(*)");
    if (strName.isEmpty())
    {
        return;
    }
    QString Name=strName.split("/").last();
    m_mapMutex.lock();
    m_playMap[Name]=strName;
    m_mapMutex.unlock();
    QTableWidgetItem *newItem = new QTableWidgetItem(Name);
    if(m_playMap.count() == 1 ){
        ui->tableWidget->setItem(0,0,newItem);
    }else
    {
        ui->tableWidget->setItem(m_playMap.count()-1,0,newItem);
    }

    //ui->listWidget->addItem(Name);
}

midslider类 

#ifndef MIDSLIDER_H
#define MIDSLIDER_H

#include <QObject>
#include <QSlider>
#include <QWidget>
#include <QMouseEvent>

class MidSlider : public QSlider
{
    Q_OBJECT
public:
    MidSlider(QWidget *parent = 0);
    ~MidSlider();

protected:
    void mousePressEvent(QMouseEvent *ev);//鼠标按下事件

private:
    void initData();

};

#endif // MIDSLIDER_H
#include "midslider.h"

MidSlider::MidSlider(QWidget *parent):QSlider(parent) {
    initData();
}

MidSlider::~MidSlider()
{

}

//鼠标按下事件
void MidSlider::mousePressEvent(QMouseEvent *ev)
{
    double pos = (double)ev->pos().x() / (double)width();//当前鼠标位置比率
    setValue(pos*this->maximum());//设置位置
    QSlider::mousePressEvent(ev);
}


void MidSlider::initData()
{
    setOrientation(Qt::Horizontal);
    //setFixedHeight(15);

    this->setStyleSheet(
    "QSlider{background-color: transparent;}"
    "QSlider::groove:horizontal {border: 0px solid #09A1FF;\
    background: #09A1FF;\
    height: 3px;\
    border-radius: 6px;\
    padding-left:0px;\
    padding-right:0px;\
    left:1px;right:0px;\
    }"
    "QSlider::sub-page:horizontal {\
    background: #09A1FF;\
    border: 1px solid #09A1FF;\
    height: 3px;\
    border-radius: 3px;\
    }"
    "QSlider::add-page:horizontal {\
    background: #696969;\
    border: 0px solid #696969;\
    height: 3px;\
    border-radius: 3px;\
    }"
    "QSlider::handle:horizontal {\
    background:#FFFFFF;\
    width: 12px;height 12px;\
    margin-top: -5px;\
    margin-bottom: -5px;\
    border-radius: 6px;\
    }");

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2074565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣最热一百题——6.三数之和

目录 题目链接&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示 解法一&#xff1a;双指针 代码分析 总结 没啥多说的&#xff0c;就是最近CS根本上不了分谢谢。 题目链接&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&…

NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis 精读

1 传统视图合成和NeRF&#xff08;Neural Radiance Fields&#xff09; 1.1 联系 传统视图合成和NeRF的共同目标都是从已有的视角图像中生成新的视角图像。两者都利用已有的多视角图像数据来预测或合成从未见过的视角。 1.2 区别 1.2.1 几何表示方式 传统视图合成&#xff…

frameworks 之InputReader

frameworks 之InputReader InputManagerService 初始化InputManagerService 启动InputReader 事件的读取设备节点注册和监听设备输入事件的读取 InputReader 事件的处理设备的添加和删除处理触摸事件的处理数据的加工和分发 android 输入事件 主要分 2个流程 事件读取 和 事件…

先进提示词工程

大型语言模型 (LLM) 的普及彻底改变了我们人类解决问题的方式。在过去&#xff0c;用计算机解决任何任务&#xff08;例如&#xff0c;重新格式化文档或对句子进行分类&#xff09;都需要创建一个程序&#xff08;即根据某种编程语言精确编写的一组命令&#xff09;。使用 LLM&…

ssrf实现.SSH未创建写shell

一、介绍SSRF漏洞 SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求&#xff0c;由服务端发起请求的安全漏洞。一般情况下&#xff0c;SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的&#xff0c;所以服务端能请求到与自身相…

Openvino2024.3版部署YOLO (C++)

在网上很少看到有2024版的openvino&#xff0c;老版本的接口很多也都不在了&#xff0c;此篇写出来也算是为了防止自己忘记。 openvino下载 下载英特尔发行版 OpenVINO 工具套件 (intel.com) 下载好后解压出来&#xff0c;放C盘D盘都一样&#xff0c;我放在D盘了&#xff0c;…

如何解决 Cloudflare | 使用 Puppeteer 和 Node.JS

我认为&#xff0c;现在自动化任务越多&#xff0c;越能体现它们的价值&#xff0c;因此挑战也变得更加明显和困难。例如&#xff0c;Cloudflare 目前提供了强有力的安全措施来保护网站免受所有形式的自动化工具的侵扰。 但对于从事自动化项目&#xff08;如网络爬虫、数据提取…

STM32(七):定时器——输入捕获

IC&#xff08;Input Capture&#xff09;输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前CNT的值将被锁存到CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。 每个高级定时器和通用定时器都拥有4个输…

基于vscode安装EPS-IDF环境与创建例程

安装ESP-IDF 在vscode中安装esp-idf插件 然后打开插件&#xff0c;左侧选择Configure ESP-IDF Extension ![![[Pasted image 20240821221256.png]](https://i-blog.csdnimg.cn/direct/3993e22c37644097b464aef0bbc244a5.png) 点击安装 自动下载ESP-IDF 安装完成&#xff01…

计算机毕业设计推荐- 基于Python的高校岗位招聘数据分析平台

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于Python的高校岗位招聘分…

Gitee的使用方法

是跟着这位up的视频学习的&#xff0c;老师讲的很好 https://www.bilibili.com/video/BV1hf4y1W7yT/share_sourcecopy_web&vd_source985ed259d2e2be1d81c218c58be165b9 需要的安装包我学习完成后&#xff0c;会放到我的gitee仓库里&#xff0c;也当作是练习一下。 insta…

PriorMapNet:Enhancing Online Vectorized HD Map Construction with Priors

参考代码&#xff1a;None 动机与出发点 训练场景中的车道线千变万化会导致query方式预测方式变得较难收敛或者性能较低&#xff0c;之前的一些工作有将mask信息引入到pipeline中为query提供instance-level的语义信息&#xff0c;但是对于point-level信息就需要自己去学习了。…

动态规划:从记忆化搜索到递推 打家劫舍

目录 LeetCode198 打家劫舍 1、递归搜索保存计算结果记忆化搜索 2、1:1翻译成递推 3、空间优化 LeetCode213 打家劫舍II LeetCode198 打家劫舍 1、递归搜索保存计算结果记忆化搜索 回溯三问&#xff1a; &#xff08;1&#xff09;当前操作&#xff1f;枚举第i个房子选/不…

计算机的错误计算(七十三)

摘要 计算机的错误计算&#xff08;七十二&#xff09;探讨了大数的余割函数的错误计算 。本节讨论另外一类数值&#xff1a; 附近数 的余割函数的计算精度问题。 例1. 已知 计算 csc(x) . 若在 Excel 中计算&#xff0c;则有 若用Java 编程实现 , 即有下列代码&#x…

认知杂谈26

今天分享 有人说的一段争议性的话 I I 上班的双刃剑&#xff1a;安稳与束缚的较量 上班这事儿啊&#xff0c;好多人都觉得那就是稳定的代表。每天按时去打卡&#xff0c;每个月都能稳稳地拿到工资&#xff0c;听起来好像挺美的&#xff0c;就跟理想生活似的。但咱要是仔细琢…

UE管理内容 —— FBX Asset Metadata Pipeline

随着实时3D制作大小和复杂程度的增加&#xff0c;以及构成现代制作流程的工具数量的不断增加&#xff0c;增加智能自动化来提高美术效率变得越发重要&#xff1b;这种智能自动化通常主要依靠元数据&#xff1a;有关资源的自定义数据&#xff0c;在项目中为资源赋予意义&#xf…

基于GA遗传优化的三维空间WSN网络最优节点部署算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 空间覆盖度模型 基于GA的优化方法 5.完整程序 1.程序功能描述 基于GA遗传优化的三维空间WSN网络最优节点部署算法matlab仿真。分别对三维空间的节点覆盖率&#xff0c;节点覆盖使用数量进行…

为什么走线宽度不同会引起阻抗畸变

事先说明&#xff1a;内容不是原创&#xff0c;或者只是自己的技术总结。仅仅用于本人日常记录 1 参考博客 参考博客来源&#xff1a; 原博客 2 基本知识点 2.1 为什么阻抗突变会引起反射 信号沿传输线传播时&#xff0c;其路径上的每一步&#xff0c;都有相应的瞬时阻抗&…

项目需求 | vscode远程免密登录Linux服务器指南-含所需的命令和步骤

步骤1&#xff1a;安装Remote - SSH扩展 在VSCode中&#xff0c;打开扩展视图&#xff0c;搜索并安装Remote Development扩展包&#xff0c;它包含了Remote - SSH扩展。 步骤2&#xff1a;生成SSH密钥对 在本地计算机上打开终端或命令提示符&#xff0c;执行以下命令&#…

约瑟夫环问题【算法 06】

约瑟夫环问题 约瑟夫环&#xff08;Josephus Problem&#xff09;是一个经典的数学和计算问题&#xff0c;其核心是解决在一群人围成一圈&#xff0c;每隔一定人数就淘汰一个人&#xff0c;最后剩下的那个人的编号。 问题描述 假设有 ( n ) 个人围成一圈&#xff0c;从第一个…