[QT/C + +] a video player based on A-SOUL element developed by QT (with source code)

preface

  as a sophomore, the author wrote a software based on QT, but the teacher refused to let us design games (GaN!) After consulting the teacher, he said let me design a video player, so I watched the video and typed the code myself (because the teacher's teaching level was too poor)

   to tell the truth, it was a little numb to get this big homework task at the beginning, because QT and C + + had not learned at all, and they had to learn and live from scratch (). At that time, may day was led by A-SOUL, and the rat thought otherwise to be a video player about A-SOUL (but in fact, they just incorporated their factors into the program).
   then I finished the dark horse's C + + and QT courses at 1.5 times the speed from station B. the C + + course knocked the first big homework in the video, and QT didn't have time to knock. Then I went to see the excellent design of dark horse about QT - video player, good guy. I thought I would fish directly, and I would finish it by knocking. Then I found that, brother, you haven't finished yet, No?? I just finished the basic functions. Hey, then I moved to another video, but it was developed with linux. I thought there was no difference between windows and linux. I knocked several P videos. As soon as I ran it, good guy, I was deceived. Should I report an error or report an error. Well, I can only refer to the articles of previous leaders on CSDN and sew them one by one in combination with the knowledge I just learned.

   I would like to thank the authors of these articles I refer to, and there are many authors. Because I read too much, I don't remember the name (sorry!), I won't list them one by one.

All help the development of video player more or less. Thank you again!

Special thanks to the big guy of rabbit sauce. My list function is to brazenly copy his

   because it's the first time I came into contact with QT, the code is certainly not very good-looking. Maybe there are even some redundant codes in the source code. No doubt, I forgot to delete them, but it's a little too troublesome to delete them (just a lazy dog). Therefore, people who download the source code may be a little tortured when they see them. Because time is very tight, some codes are stitched, but only achieve the function, The mouse didn't fully understand it (yes, it refers to most of the functions in the list). I'm sorry

Note:
   the icon was designed by a big man in station B, and the color was changed, but the dynamic of turning over Jabu was still not found in April (maybe deleted?)
  the background is the background of the past events in Zhijiang, but I don't know who the original author is. I'm sorry here. Thank you very much if someone can talk to the original author. If you don't want to be used, I'll delete it

1, Software instructions

1. The interface for running the software is as follows:

Overall interface:

The top left corner is the open file button:

Below is the video progress bar

The lower left corner is the timeline, the left is the playing time of the current video, and the right is the total time of the video

The lower middle is the play control button, from left to right: previous video, pause / play, next video

Next to it are volume control buttons and volume control progress bar

The bottom right corner is the maximize / minimize button

The upper right corner is the window control button, from left to right: minimize, maximize / normalize, close (not exit, just exit to the tray)

On the right is the playlist display

2. Steps of operating the software

First, right-click the list and click "empty playlist"

Playlist empty:

Then click the "open button" in the upper right corner:

After clicking, the following page will appear:

Select the video to be added and click to open it. The corresponding video file name will appear in the list:

You can also right-click the list and click "add file"

The addition process is the same as above and will not be repeated.

In the list, you can right-click a video entry to expand the options of the list:

Delete selected item: delete the item
Open file directory: open the directory where the file is located

Double click the file you want to play to play

You can also right-click in the list and click "play" to play

Double click the page to make it full screen

Also available through

In the lower right corner
(full screen button)

Or in the upper right corner
(Window maximize button)

Maximize pages

During play / pause, you can click the button on the left side of the list to hide the list

The effect is as follows:

In the process of playing, you can click the progress bar or drag the progress bar to jump the video progress. Similarly, the volume key can also be used. In addition, you can directly click the volume key to mute, and click again to restore to the last adjusted volume value

During playback, video events can be controlled through the keyboard
Space: control video playback / pause
Direction key ↑: control volume+
Direction key ↓: control volume-
Direction key ←: control video progress backward
Direction key →: control video progress fast forward
ESC: restore the normal interface in the full screen state

During playback, you can:

Play the previous video / next video, or go to the next video after the video is played automatically. When it reaches the last one in the list, it will automatically cycle to the first player in the list

Introduction to the buttons in the upper right corner

From left to right: minimize, maximize / normalize, close (not exit, just exit to tray)
Click minimize to narrow the program to the taskbar (the video remains in the state before minimization)

Maximize

close:
A message appears in the lower right corner and the video pauses

Display in tray:

You can restore the main page by clicking / right clicking the menu that appears


Click exit to exit the program

2, Software design description

1.UI interface design

The video playback interface uses widget controls to upgrade to the QVideowidget class. The buttons use ordinary push buttons. The progress bar and buttons use the upgrade style sheet to change the appearance. In particular, the ListView control can only modify the style in the code instead of changing the style by upgrading the style sheet in the UI

code

2. Some functions in the main code

In the constructor:

By monitoring each key, the purpose of controlling the program with the key is achieved

    ui->btn_volume->installEventFilter(this);
    ui->fullscreenBtn->installEventFilter(this);
    ui->btn_previous->installEventFilter(this);
    ui->btn_next->installEventFilter(this);
    ui->btn_maxnized->installEventFilter(this);
    ui->btn_closed->installEventFilter(this);
    ui->btn_minnized->installEventFilter(this);
    ui->listView->installEventFilter(this);
    installEventFilter(this);

Set the background and style of ListView

    QPixmap pixmap = QPixmap(":/A-SOUL/listview_background.png").scaled(ui->listView->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
    QPalette palette(ui->listView->palette());
    palette.setBrush(QPalette::Background, QBrush(pixmap));
    ui->listView->setPalette(palette);
    setStyleSheet("QListView{background-image: url(:/A-SOUL/listview_background.png);background-attachment: scroll;background-repeat: repeat-xy;}QListView{alternate-background-color: yellow;}QListView{show-decoration-selected: 1; }QListView::item:alternate {background: #EEEEEE;} QListView::item:selected {border: 1px solid #6a6ea9;}QListView::item:selected:!active {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #ABAFE5, stop: 1 #8588B2);}QListView::item:selected:active {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6a6ea9, stop: 1 #888dd9);}QListView::item:hover {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FAFBFE, stop: 1 #DCDEF1);}");

Functions related to Widget playback events:

  //Set playback properties
        //1. Monitoring signal variation function
        connect(mediaPlayer,SIGNAL(mediaStateChanged(QMediaPlayer::State)),this,SLOT(mediaStateChanged(QMediaPlayer::State)));

        //2. Play progress signal change function
        connect(mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(positionChanged(qint64)));

        //3. Playback length signal change
        connect(mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(durationChanged(qint64)));

        //4. Set playback error Association
        connect(mediaPlayer,SIGNAL(error(QMediaPlayer::Error)),this,SLOT(handleError()));

        //Play end Association
        connect(mediaPlayer,SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),this,SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));


        //Total playback time contact display
        connect(mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(getduration()));

        //Playing time correlation function
        connect(mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(setPlayTime()));

Event associated with change of progress bar volume photo:

        connect(ui->horizontalSlider_volume,SIGNAL(valueChanged(int)),this,SLOT(volpicchange(int)));
        connect(ui->horizontalSlider_volume,SIGNAL(sliderMoved(int)),this,SLOT(volpicchange(int)));
        connect(ui->horizontalSlider_volume,SIGNAL(valueChanged(int)),mediaPlayer,SLOT(setVolume(int)));
        connect(ui->horizontalSlider_volume,SIGNAL(sliderMoved(int)),mediaPlayer,SLOT(setVolume(int)));
        connect(ui->horizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(setPosition(int)));

Association of key events:

        connect(ui->listView,&MediaListView::doubleClicked,this,&MainWindow::selectListView);
        connect(ui->btn_previous,&QPushButton::clicked,ui->listView,&MediaListView::previous);
        connect(ui->btn_next,&QPushButton::clicked,ui->listView,&MediaListView::next);
        connect(ui->btn_open,&QPushButton::clicked,ui->listView,&MediaListView::openinit);
        connect(ui->listView,&MediaListView::deleteIndex,mediaPlayer,&QMediaPlayer::stop);
        connect(ui->listView,&MediaListView::playIndex,this,&MainWindow::selectListView);

Functions for pallet events:

    // Create system tray icon
    trayIcon = new QSystemTrayIcon(QIcon(":/A-SOUL/bella_purple.webp"), this);
    trayIcon->setToolTip(tr("Video player FOR A-SOUL -- Flowing works"));

 // create menu
    QMenu *trayMenu=new QMenu();
    openAction=new QAction(tr("open"),this);
    quitAction=new QAction(tr("sign out"),this);


    //Menu icon settings
    openAction->setIcon(QIcon(":/A-SOUL/tray_open.png"));
    quitAction->setIcon(QIcon(":/A-SOUL/close.png"));




    trayMenu->setStyleSheet(
                         "\
                         QMenu {\
                         background-color:#503d68; /* Whole background*/\
                         /*border: 3px solid rgb(235,110,36);Entire menu edge*/\
                         }\
                     QMenu::item {\
                         font-size: 10pt; \
                         font-family: Alibaba Pratt & Whitney M, serif;\
                         color: #db8aa4;  /* Font color*/\
                         border: 3px solid #fff7f6;    /*item checkbox*/\
                         background-color:#503d68;\
                         padding:1px 22px; /*Set the up, down, left and right inner margins of the menu item text. The effect is that there is a gap between the left and right up and down of the menu items*/\
                         margin:0px 0px;/*Sets the outer margin of the menu item*/\
                          }\
                     QMenu::item:selected { \
                         background-color:#a5a3d2;/* Selected style*/\
                         }\
                     QMenu::item:pressed {/*Menu item pressing effect*/\
                                               border: 1px solid #503d68; \
                                               background-color:#5b4075; \
                                           }\
                        ");

    //Event connection
    trayMenu->addAction(openAction);
    connect(openAction,SIGNAL(triggered(bool)),this,SLOT(showNormal()));
    trayMenu->addAction(quitAction);
    connect(quitAction,SIGNAL(triggered(bool)),this,SLOT(close_exe()));

    //Put on tray prompt
 trayIcon->setContextMenu(trayMenu);
 // The tray icon is activated for processing
 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
         this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
 // Display tray icon
 trayIcon->show();

Function of double click / maximize button (because the function is similar, only the function of double click maximize event is displayed):

    if(ui->btn_maxnized->property("max").toBool())
    {

        //If in normal mode?
        ui->btn_maxnized->setProperty("max",false);
        ui->btn_maxnized->setToolTip("Full screen");

        ui->fullscreenBtn->setProperty("max",false);
        ui->fullscreenBtn->setToolTip("Full screen");




        ui->btn_maxnized->setIcon(QPixmap(":/A-SOUL/maxnizied.png"));
        ui->fullscreenBtn->setIcon(QPixmap(":/A-SOUL/max_screen.png"));
        showNormal();



    }
    else
    {



        ui->fullscreenBtn->setProperty("max",true);
        ui->fullscreenBtn->setToolTip("reduction");
        ui->btn_maxnized->setProperty("max",true);
        ui->btn_maxnized->setToolTip("reduction");

        ui->btn_maxnized->setIcon(QPixmap(":/A-SOUL/normal_windows.png"));
        ui->fullscreenBtn->setIcon(QPixmap(":/A-SOUL/min_screen.png"));



        ui->widget->show();
        showMaximized();


    }

    ui->btn_maxnized->update();

Filter event function of each key:

//Filter events for spacebar keys (pause)

        if(event->type() == QEvent :: KeyPress){
            QKeyEvent *keyEvent =static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Space){

                on_toolButton_clicked();


                return true;
            }

        }
//Filter event of left direction key (back)

        if(event->type() == QEvent :: KeyPress){
            QKeyEvent *keyEvent =static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Left){
                mediaPlayer->setPosition(mediaPlayer->position()-500);
                ui->horizontalSlider->setValue(mediaPlayer->position()-500);
                return true;
            }

        }
//Filter event of right button in direction (fast forward)

        if(event->type() == QEvent :: KeyPress){
            QKeyEvent *keyEvent =static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Right){

                mediaPlayer->setPosition(mediaPlayer->position()+500);
                ui->horizontalSlider->setValue(mediaPlayer->position()+500);

                return true;
            }

        }

//Filter events for keys in the direction (volume up)

        if(event->type() == QEvent :: KeyPress){
            QKeyEvent *keyEvent =static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Up){

                mediaPlayer->setVolume(vol+5);
                ui->horizontalSlider_volume->setValue(vol+5);


                vol=mediaPlayer->volume();

                return true;
            }

        }

//Filter event of the down direction key (decrease volume)

        if(event->type() == QEvent :: KeyPress){
            QKeyEvent *keyEvent =static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Down){

                mediaPlayer->setVolume(mediaPlayer->volume()-5);
                ui->horizontalSlider_volume->setValue(mediaPlayer->volume()-5);


                vol=mediaPlayer->volume();
                return true;
            }

        }


The functions of page stretching and pressing and moving are too miscellaneous to be shown here

Function of closing function by pressing the close button in the upper right corner:

if (isVisible()) {
        this->hide();

        if(mediaPlayer->state()==QMediaPlayer::PlayingState)
        {
            mediaPlayer->pause();
            //When you pause
            ui->toolButton->setToolTip("play");
            ui->toolButton->setAutoRaise(true);
            ui->toolButton->setIcon(QPixmap(":/A-SOUL/play_key.png"));
        }



        trayIcon->showMessage(tr("Video player FOR A-SOUL"), tr("Flowing works"));
        event->ignore();
    }


The middle and lower pause buttons realize the function of play / pause:

if(mediaPlayer->isAudioAvailable()==true)//It's only useful if there's a video to play, otherwise it won't respond (if you don't press this line, the program will crash)
{
        if(mediaPlayer->state()==QMediaPlayer::PlayingState)
        {
            mediaPlayer->pause();
            //When you pause

            ui->toolButton->setToolTip("play");
            ui->toolButton->setAutoRaise(true);
            ui->toolButton->setIcon(QPixmap(":/A-SOUL/play_key.png"));
        }
        else
        {
        if(mediaPlayer->isAudioAvailable()==true)//You can't press the button without music input
        {
        mediaPlayer->play();
        //When playing
        ui->toolButton->setToolTip("suspend");
        ui->toolButton->setAutoRaise(true);
        ui->toolButton->setIcon(QPixmap(":/A-SOUL/pause_key.png"));



        }
        }

}

Function of volume picture change:

if(vol==0)
    {
        ui->btn_volume->setProperty("silence", true);
        ui->btn_volume->setToolTip("Mute");
        ui->btn_volume->setIcon(QPixmap(":/A-SOUL/mute_volume.png"));
    }
   else if(vol<70)
    {
        ui->btn_volume->setProperty("silence", false);
        ui->btn_volume->setToolTip("volume");
        ui->btn_volume->setIcon(QPixmap(":/A-SOUL/mediem_voleum.png"));
    }
    else
    {
        ui->btn_volume->setProperty("silence", false);

        ui->btn_volume->setToolTip("volume");
        ui->btn_volume->setIcon(QPixmap(":/A-SOUL/full_volume.png"));
    }

    QToolTip::showText(QCursor::pos(),QString::number(vol));//Obtain this value through the slidermove of vol. / / it is used to pass the value to the tooltip for real-time display

3.myslider function

Click the function to move the progress bar to the corresponding position:

 //Get the current click position
    int currentX = ev->pos().x();

    //Get the percentage of the current clicked position in the whole Slider
    double per = currentX *1.0 /this->width();

    //Use the calculated percentage to get specific figures
    int value = per*(this->maximum() - this->minimum()) + this->minimum();

//    qDebug() << value;

    //Set slider position
    this->setValue(value);

    //mousePressEvent is also used in events such as Slider movement events. This sentence is added to avoid affecting it. Yes, the Slider can normally correspond to other mouse events
    QSlider::mousePressEvent(ev);


3. Some functions of the list (medialistview.cpp)

Open file function (same as the button in the upper left corner):

   QStringList array = QFileDialog::getOpenFileNames(this,"Files to play","F:/QT TEXT/a_soul/video_player/A-SOUL/video","video(*.mp4 *.avi *.rmvb)");

               if(array.length()<=0){
                   return;
               }
               playList = array;

               for(playIndex_temp = 0;playIndex_temp < playList.length(); playIndex_temp++){
               m_model->insert(QUrl::fromLocalFile(playList.at(playIndex_temp)));//The file is displayed in the list

        }
               playIndex_temp = 0;//Playlist reset to 0



              //Forget it, don't play it automatically. It's not that much to play it manually

Previous video (the principle of the next video is the same, so only one is displayed):

 auto index =m_model->currentIndex();
    index = model()->index(index.row()-1,0);



        if(index.row()==-1)
        {
            index=model()->index(model()->rowCount(QModelIndex())-1,0);
        }

    setCurrentIndex(index);
    emit playIndex(index);

Delete an entry function:

auto indexs = selectedIndexes();
    qSort(indexs.begin(),indexs.end(),modelSort);
    foreach (auto index, indexs) {
        model()->removeRow(index.row());
        if(index ==m_model->currentIndex())
        {
            emit deleteIndex();
        }
    }

Delete list function:

  model()->removeRows(0,model()->rowCount(QModelIndex()),QModelIndex());
    emit deleteIndex();

Open file directory function:

auto url =m_model->media(currentIndex()).canonicalUrl();
    if(url.isLocalFile())
    {
        QFileInfo info(url.path());
        QDesktopServices::openUrl(QUrl::fromLocalFile( info.dir().path()));
    }

For the function of hiding the list, it is recommended to see hideshowlistview CPP function

Since then, the function to realize the general function has been introduced

epilogue

1. Onset TIME

Finally, it is strongly recommended to jump the source code of TIME!


The font is Ranran powder, the border / background is the color of Nailin and rajie, the suspension is the color of late, and the color of Jiale when pressed

The suspension is light purple in the evening. Pressing it is the deep purple of Jiale. Sister La is the captain. She must make an icon. Sister Nailin is the first in charge of the field and is responsible for dragging the button. Of course, the most important thing is to open the button and integrate you into the program. It belongs to the gentle pinch of rats

2. Download the source code

Download all source code:

Link: https://pan.baidu.com/s/1kJVr6edoNeoXvuTTl1LujA
Extraction code: nqx9

Station B pays attention to Nailin Queen. The first sentence of automatic reply is to decompress the password

   before, I also wrote a perpetual calendar and traffic light system for the big homework of single chip microcomputer. I'll write it when I'm free

Keywords: Qt list

Added by plutoplanet on Sat, 29 Jan 2022 22:47:53 +0200