SoundBoard in C++ Using Qt

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I've been working on a soundboard software for tabletop games audio immersion in C++ using Qt. The software consists of 2 tabs who provides to a game master a set of individual sounds or scenes to be payed for a particular moment in the game.



The game master can choose the audio to play and the audio is embedded in a resource file from Qt. Besides taking almost 1.5 GB in ram (which have to be wrong), in general the software is running fine, the thing is for the past 2 weeks I feel like I'm not using C++ and Qt the way they are meant to. I'm just pretending to.



I try to come up with C++ 11, 14 and 17 as well as the "Qt way" standards to code (why I'm forced to create so many pointers: the compiler complains when I don't create one...) but it's just not as straightforward as I would like it to be. I want my code to be more elegant, more expressive, more verbose and efficient when running.



If anyone can take the time and point out where my weak spots are in general and what should be my thought process when writing code that would be of great help. If this is not the right place to ask for a code review of like this I'm sure you will point me out on the right direction.



.pro



QT += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SoundBoard
TEMPLATE = app

CONFIG += resources_big

RC_ICONS = Codex_book.ico

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES +=
main.cpp
widget.cpp
customlistwidget.cpp
customlistwidgetitem.cpp
customtabwidget.cpp
player.cpp
scene.cpp

HEADERS +=
widget.h
customlistwidget.h
customlistwidgetitem.h
customtabwidget.h
player.h
scene.h

FORMS +=
widget.ui
player.ui
scene.ui
player.ui

RESOURCES +=
src.qrc


Headers:



customlistwidget.h



#ifndef CUSTOMLISTWIDGET_H
#define CUSTOMLISTWIDGET_H

#include <QListWidget>
#include <QVector>

#include "customlistwidgetitem.h"

class CustomListWidget : public QListWidget
Q_OBJECT
public:
CustomListWidget(QWidget *parent = nullptr);

void addCustomItem(CustomListWidgetItem*);

public slots:
void setItemPressed(QListWidgetItem*);
void emitCustomItem(QListWidgetItem*);

signals:
void customItem(CustomListWidgetItem*);

protected:
void startDrag(Qt::DropActions supportedActions);

private:
QVector<CustomListWidgetItem*> list;
QListWidgetItem *itemToBeSet;
;

#endif // CUSTOMLISTWIDGET_H


customlistwidgetitem.h



#ifndef CUSTOMLISTWIDGETITEM_H
#define CUSTOMLISTWIDGETITEM_H

#include <QListWidgetItem>
#include <QFileInfo>

class CustomListWidgetItem : public QListWidgetItem
public:
CustomListWidgetItem(QFileInfo, QIcon, QListWidget *parent = nullptr);
~CustomListWidgetItem();

QFileInfo getFileInfo();

private:
QFileInfo fileInfo;
;

#endif // CUSTOMLISTWIDGETITEM_H


customtabwidget.h



#ifndef CUSTOMTABWIDGET_H
#define CUSTOMTABWIDGET_H

#include <QTabWidget>
#include <QWidget>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>

#include <QScrollArea>

#include <QPushButton>

#include <QVector>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "scene.h"
#include "player.h"
#include "customlistwidgetitem.h"

class CustomTabWidget : public QTabWidget
Q_OBJECT

public:
CustomTabWidget(QWidget *parent = nullptr);

void setSoundLayout();
void setSceneLayout();

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

public slots:
void addScene(bool);
void stopAllScenes(bool);
void removeScene(Scene*);
void removeAllScenes(bool);


void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player*);
void removeAllSounds(bool);

void addDefaultSound(CustomListWidgetItem*);

private:
void appendSound(QStringList &, int);
void appendScene(QString);

QVector<Scene*> scenes;
QVector<Player*> players;

QGridLayout *soundGrid;
QGridLayout *sceneGrid;

QWidget *soundPanel;
QWidget *scenePanel;

QHBoxLayout *soundPanelLayout;
QHBoxLayout *scenePanelLayout;

QHBoxLayout *hSoundLayout;
QVBoxLayout *vSoundLayout;

QHBoxLayout *hSceneLayout;
QVBoxLayout *vSceneLayout;

int soundCol;
int soundRow;

int sceneCol;
int sceneRow;

QPushButton *addSoundButton;
QPushButton *removeAllSoundsButton;
QPushButton *stopAllSoundsButton;

QPushButton *addSceneButton;
QPushButton *removeAllScenesButton;
QPushButton *stopAllScenesButton;

QScrollArea *scrollSound;
QScrollArea *scrollScene;

QWidget *soundScroll;
QWidget *sceneScroll;
;

#endif // CUSTOMTABWIDGET_H


player.h



#ifndef PLAYER_H
#define PLAYER_H

#include <QWidget>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QCheckBox>
#include <QPushButton>

namespace Ui
class Player;


class Player : public QWidget
Q_OBJECT

public:
explicit Player(QWidget *parent = 0);
~Player();

void setTitle(QString);
void setIconState(QString);

QMediaPlaylist *getPlaylist();
QMediaPlayer *getPlayer();
QCheckBox* getLoopButton();
QPushButton* getPlayStopButton();
float getSliderValue();

public slots:
void playStopButton(bool);
void soundEnd(QMediaPlayer::State);
void loop(bool);
void emitThisPlayer(bool);

signals:
void thisPlayer(Player*);
void stateChanged(QMediaPlayer::State);
void sliderValueChanged(int);

private:
Ui::Player *ui;

QMediaPlayer *mPlayer;
QMediaPlaylist *mPlaylist;

float volume;
;

#endif // PLAYER_H


scene.h



#ifndef SCENE_H
#define SCENE_H

#include <QWidget>
#include <QPushButton>
#include <QGridLayout>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "player.h"
#include "customlistwidget.h"

namespace Ui
class Scene;


class Scene;

class Editor : public QWidget
Q_OBJECT

public:
explicit Editor(Scene *parent = 0);
~Editor();

void addDefaultSound(CustomListWidgetItem*);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

void resizeEvent(QResizeEvent *evt);
void closeEvent(QCloseEvent *event);

signals:
void hidden(bool);

private:
Scene *scene;
;

class Scene : public QWidget
Q_OBJECT

public:
explicit Scene(QWidget *parent = 0);
~Scene();

void appendSound(QStringList, int);

int getCol();
void setCol(int);

int getRow();
void setRow(int);

void setTitle(QString);
QPushButton *getPlayStopButton();

public slots:
void emitThisScene(bool);
void showEditor(bool);
void playStop(bool);
void loopScene(bool);
void playerStateChanged(QMediaPlayer::State);
void soundEnd();
void masterVolume(int);
void setMasterVolume(int);

void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player *player);
void removeAllSounds(bool);

signals:
void thisScene(Scene*);

private:
void setEditorLayout();

Ui::Scene *ui;
QVector<Player*> players;

Editor *editor;

QPushButton *add;
QPushButton *stopAll;
QPushButton *removeAll;
QPushButton *editorPS;

QGridLayout *grid;
QWidget *panel;

QHBoxLayout *h;
QVBoxLayout *v;

QHBoxLayout *panelLayout;

int col;
int row;

int stoppedCounter;
;

#endif // SCENE_H


widget.h



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui
class Widget;


class Widget : public QWidget
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
;

#endif // WIDGET_H


Sources:



customlistwidget.cpp



#include "customlistwidget.h"

#include <QMouseEvent>

#include <QMimeData>
#include <QDrag>

#include <QList>
#include <QUrl>

#include <QByteArray>

#include <QDebug>

CustomListWidget::CustomListWidget(QWidget *parent) : QListWidget(parent)

setMouseTracking(true);

setDragEnabled(true);
setDragDropMode(QListWidget::DragOnly);

connect(this, &CustomListWidget::itemEntered, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemClicked, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemDoubleClicked, this, &CustomListWidget::emitCustomItem);
itemToBeSet = nullptr;

setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);


void CustomListWidget::addCustomItem(CustomListWidgetItem *customItem)
list.push_back(customItem);
qDebug() << "Custom Item Added: " << list.size() << endl;
QListWidgetItem *item = new QListWidgetItem(this);
item->setText(customItem->text());
item->setIcon(customItem->icon());


void CustomListWidget::setItemPressed(QListWidgetItem *item)
itemToBeSet = item;
qDebug() << "set" << endl;


void CustomListWidget::emitCustomItem(QListWidgetItem *item)
for(int i = 0; i < list.size(); ++i)
if(item->text() == list.at(i)->getFileInfo().baseName())
emit customItem(list.at(i));




void CustomListWidget::startDrag(Qt::DropActions supportedActions)
(void)supportedActions;
QList<QUrl> url;

QByteArray ba;

QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;

if(itemToBeSet)
for(int i = 0; i < list.size(); ++i)
if(itemToBeSet->text() == list.at(i)->text())
ba.append(list.at(i)->getFileInfo().absoluteFilePath());




mimeData->setData("FileInfo", ba);

drag->setMimeData(mimeData);
drag->exec();



customlistwidgetitem.cpp



#include "customlistwidgetitem.h"

#include <QDebug>

CustomListWidgetItem::CustomListWidgetItem(QFileInfo infoFile, QIcon icon, QListWidget *parent)
: QListWidgetItem(parent)

fileInfo = infoFile;

setText(infoFile.baseName());
setIcon(icon);


CustomListWidgetItem::~CustomListWidgetItem()
delete &fileInfo;


QFileInfo CustomListWidgetItem::getFileInfo()
return fileInfo;



customtabwidget.cpp



#include "customtabwidget.h"

#include "customlistwidget.h"

#include <QMimeData>

#include <QFileDialog>
#include <QInputDialog>

CustomTabWidget::CustomTabWidget(QWidget *parent) : QTabWidget(parent)

scrollSound = new QScrollArea(this);
soundScroll = new QWidget(scrollSound);
soundScroll->setStyleSheet("background-image: url(:/images/Listen.png");

scrollSound->setWidgetResizable(true);
soundScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSoundLayout();

scrollScene = new QScrollArea(this);
sceneScroll = new QWidget(scrollScene);
scrollScene->setWidgetResizable(true);
sceneScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSceneLayout();

scrollSound->setWidget(soundScroll);
scrollScene->setWidget(sceneScroll);

addTab(scrollSound, "Sounds");
addTab(scrollScene, "Ambience");

setAcceptDrops(true);

connect(addSoundButton, &QPushButton::clicked, this, &CustomTabWidget::addSound);
connect(stopAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllSounds);
connect(removeAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllSounds);

connect(addSceneButton, &QPushButton::clicked, this, &CustomTabWidget::addScene);
connect(stopAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllScenes);
connect(removeAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllScenes);


void CustomTabWidget::setSoundLayout()
CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



connect(listWidget, &CustomListWidget::customItem, this, &CustomTabWidget::addDefaultSound);

soundCol = 0;
soundRow = 0;

addSoundButton = new QPushButton;
stopAllSoundsButton = new QPushButton;
removeAllSoundsButton = new QPushButton;

addSoundButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSoundButton->setStyleSheet("background-color: transparent;");
addSoundButton->setIcon(QIcon(QPixmap(":icons/add.png")));
addSoundButton->setIconSize(QSize(38, 38));
addSoundButton->setToolTip("Add Mp3 Track");
addSoundButton->setToolTipDuration(1000);

stopAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllSoundsButton->setStyleSheet("background-color: transparent;");
stopAllSoundsButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllSoundsButton->setIconSize(QSize(38, 38));
stopAllSoundsButton->setToolTip("Stop All Tracks");
stopAllSoundsButton->setToolTipDuration(1000);

removeAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllSoundsButton->setStyleSheet("background-color: transparent;");
removeAllSoundsButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllSoundsButton->setIconSize(QSize(38, 38));
removeAllSoundsButton->setToolTip("Remove All Tracks");
removeAllSoundsButton->setToolTipDuration(1000);

soundPanel = new QWidget;
soundPanelLayout = new QHBoxLayout;

soundGrid = new QGridLayout;

hSoundLayout = new QHBoxLayout;
vSoundLayout = new QVBoxLayout;

soundPanelLayout->addWidget(addSoundButton);
soundPanelLayout->addWidget(stopAllSoundsButton);
soundPanelLayout->addWidget(removeAllSoundsButton);
soundPanelLayout->addStretch(1);

soundPanel->setLayout(soundPanelLayout);

hSoundLayout->addLayout(soundGrid);
hSoundLayout->addStretch(1);

vSoundLayout->addWidget(soundPanel);
vSoundLayout->addLayout(hSoundLayout);
vSoundLayout->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(vSoundLayout);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

soundScroll->setLayout(finalLayout);


void CustomTabWidget::setSceneLayout()
sceneCol = 0;
sceneRow = 0;

addSceneButton = new QPushButton;
stopAllScenesButton = new QPushButton;
removeAllScenesButton = new QPushButton;

addSceneButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSceneButton->setStyleSheet("background-color: transparent;");
addSceneButton->setIcon(QIcon(QPixmap(":icons/scene.png")));
addSceneButton->setIconSize(QSize(38, 38));
addSceneButton->setToolTip("Add Mp3 Track");
addSceneButton->setToolTipDuration(1000);

stopAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllScenesButton->setStyleSheet("background-color: transparent;");
stopAllScenesButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllScenesButton->setIconSize(QSize(38, 38));
stopAllScenesButton->setToolTip("Stop All Tracks");
stopAllScenesButton->setToolTipDuration(1000);

removeAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllScenesButton->setStyleSheet("background-color: transparent;");
removeAllScenesButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllScenesButton->setIconSize(QSize(38, 38));
removeAllScenesButton->setToolTip("Remove All Tracks");
removeAllScenesButton->setToolTipDuration(1000);

sceneGrid = new QGridLayout;
scenePanel = new QWidget;
scenePanelLayout = new QHBoxLayout;
hSceneLayout = new QHBoxLayout;
vSceneLayout = new QVBoxLayout;
sceneScroll->setLayout(vSceneLayout);

scenePanelLayout->addWidget(addSceneButton);
scenePanelLayout->addWidget(stopAllScenesButton);
scenePanelLayout->addWidget(removeAllScenesButton);

scenePanelLayout->addStretch(1);

scenePanel->setLayout(scenePanelLayout);

hSceneLayout->addLayout(sceneGrid);
hSceneLayout->addStretch(1);

vSceneLayout->addWidget(scenePanel);
vSceneLayout->addLayout(hSceneLayout);
vSceneLayout->addStretch(1);


void CustomTabWidget::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void CustomTabWidget::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dropEvent(QDropEvent *event)
QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(soundCol < 3)
appendSound(fileList, i);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(fileList, i);
++soundCol;


else
return;



void CustomTabWidget::removeSound(Player *player)
players.removeAll(player);
player->~Player();

soundGrid->~QGridLayout();
soundGrid = new QGridLayout;
hSoundLayout->insertLayout(hSoundLayout->count() - 1, soundGrid);

soundRow = 0;
soundCol = 0;
int counter = 0;
while(counter < players.size())
if(soundCol < 3)
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;
else
soundCol = 0;
++soundRow;
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;

++counter;



void CustomTabWidget::removeAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
soundCol = 0;
soundRow = 0;


void CustomTabWidget::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void CustomTabWidget::addScene(bool checked)
(void)checked;

bool ok;
QString title = QInputDialog::getText(this, "Scene Title",
"Title: ", QLineEdit::Normal,
"", &ok);
if (ok && !title.isEmpty())
if(sceneCol < 5)
appendScene(title);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
appendScene(title);
++sceneCol;

else
return;



void CustomTabWidget::stopAllScenes(bool checked)
(void)checked;
for(int i = 0; i < scenes.size(); ++i)
if(scenes.at(i)->getPlayStopButton()->isChecked())
scenes.at(i)->playStop(false);
scenes.at(i)->getPlayStopButton()->setChecked(false);
// scenes.at(i)->getPlayStopButton()->click();




void CustomTabWidget::removeScene(Scene *scene)
scenes.removeAll(scene);
scene->~Scene();

sceneGrid->~QGridLayout();
sceneGrid = new QGridLayout;
hSceneLayout->insertLayout(hSceneLayout->count() - 1, sceneGrid);

sceneRow = 0;
sceneCol = 0;
int counter = 0;
while(counter < scenes.size())
if(sceneCol < 5)
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;

++counter;



void CustomTabWidget::removeAllScenes(bool checked)
(void)checked;

for(int i = 0; i < scenes.size(); ++i)
scenes.at(i)->~Scene();

scenes.clear();
sceneCol = 0;
sceneRow = 0;


void CustomTabWidget::appendSound(QStringList &list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &CustomTabWidget::removeSound);
qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
qDebug() << file << endl;
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
soundGrid->addWidget(players.at(players.size() - 1), soundRow, soundCol);


void CustomTabWidget::appendScene(QString title)
Scene *scene = new Scene;
connect(scene, &Scene::thisScene, this, &CustomTabWidget::removeScene);
scenes.append(scene);
scene->setTitle(title);
sceneGrid->addWidget(scene, sceneRow, sceneCol);



main.cpp



#include "widget.h"
#include <QApplication>

int main(int argc, char *argv)
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();



player.cpp



#include "player.h"
#include "ui_player.h"

#include <QPainter>

Player::Player(QWidget *parent) : QWidget(parent),
ui(new Ui::Player)
ui->setupUi(this);

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setValue(50);
ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);

ui->deleteButton->setToolTip("Delete");
ui->deleteButton->setToolTipDuration(500);


mPlayer = new QMediaPlayer(this);
mPlaylist = new QMediaPlaylist(this);
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
mPlayer->setPlaylist(mPlaylist);
mPlayer->setVolume(ui->volumeSlider->value());

connect(ui->playStopButton, &QPushButton::clicked, this, &Player::playStopButton);
connect(ui->deleteButton, &QPushButton::clicked, this, &Player::emitThisPlayer);
connect(mPlayer, &QMediaPlayer::stateChanged, this, &Player::soundEnd);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Player::loop);
connect(ui->volumeSlider, &QSlider::valueChanged, mPlayer, &QMediaPlayer::setVolume);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Player::sliderValueChanged);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
setIconState("play");
ui->playStopButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Player::~Player()
delete ui;


void Player::loop(bool checked)
if(checked)
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
else
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);



void Player::soundEnd(QMediaPlayer::State state)
if(state == QMediaPlayer::State::StoppedState)
setIconState("play");
ui->playStopButton->setChecked(false);



void Player::playStopButton(bool checked)
if(checked)
setIconState("stop");
mPlayer->play();
else
setIconState("play");
if(mPlayer->state() == QMediaPlayer::State::PlayingState)
mPlayer->stop();
else
return;




void Player::setTitle(QString title)
ui->titleLabel->setText(title);


void Player::setIconState(QString str)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/" + str + ".png")));


float Player::getSliderValue()
return (float)ui->volumeSlider->value();


QPushButton* Player::getPlayStopButton()
return ui->playStopButton;


QCheckBox* Player::getLoopButton()
return ui->loopCheckBox;


QMediaPlayer *Player::getPlayer()
return mPlayer;


QMediaPlaylist *Player::getPlaylist()
return mPlaylist;


void Player::emitThisPlayer(bool checked)
(void)checked;
emit thisPlayer(this);



scene.cpp



#include "scene.h"
#include "ui_scene.h"

#include <QFileDialog>
#include <QCloseEvent>

#include <QStringList>
#include <QMimeData>

Scene::Scene(QWidget *parent) : QWidget(parent),
ui(new Ui::Scene)
ui->setupUi(this);

stoppedCounter = 0;

setEditorLayout();

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);
ui->volumeSlider->setValue(50);

ui->deleteButton->setToolTip("Delete Scene");
ui->deleteButton->setToolTipDuration(500);

connect(ui->playStopButton, &QPushButton::clicked, this, &Scene::playStop);
connect(ui->editorButton, &QPushButton::clicked, this, &Scene::showEditor);
connect(ui->deleteButton, &QPushButton::clicked, this, &Scene::emitThisScene);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Scene::loopScene);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Scene::masterVolume);

connect(add, &QPushButton::clicked, this, &Scene::addSound);
connect(stopAll, &QPushButton::clicked, this, &Scene::stopAllSounds);
connect(removeAll, &QPushButton::clicked, this, &Scene::removeAllSounds);
connect(editorPS, &QPushButton::clicked, this, &Scene::playStop);
// connect(editor, &Editor::hidden, this, &Scene::playStop);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setIconSize(QSize(28, 28));

ui->editorButton->setStyleSheet("background-color: transparent;");
ui->editorButton->setIcon(QIcon(QPixmap(":/icons/settings.png")));
ui->editorButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Scene::~Scene()
delete ui;


void Editor::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void Editor::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void Editor::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void Editor::dropEvent(QDropEvent *event)

QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



void Editor::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



int Scene::getCol()
return col;


void Scene::setCol(int i)
col = i;


int Scene::getRow()
return row;


void Scene::setRow(int i)
row = i;


Editor::Editor(Scene *parent) : QWidget(parent)
scene = parent;


void Editor::resizeEvent(QResizeEvent *evt)
QPixmap bkgnd(":/images/library wizard.jpg");
bkgnd = bkgnd.scaled(size(), Qt::IgnoreAspectRatio);
QPalette p = palette(); //copy current, not create new
p.setBrush(QPalette::Background, bkgnd);
setPalette(p);

QWidget::resizeEvent(evt); //call base implementation


void Editor::closeEvent(QCloseEvent *event)
event->ignore();
scene->stopAllSounds(true);
this->hide();

// emit hidden(false);


Editor::~Editor()



void Scene::masterVolume(int i)
for(int j = 0; j < players.size(); ++j)
players.at(j)->getPlayer()->setVolume((players.at(j)->getSliderValue() / 100) * i);



void Scene::setMasterVolume(int i)
(void)i;
masterVolume(ui->volumeSlider->value());


void Scene::soundEnd()
qDebug() << endl << "soundEnd() Emitido";
if(stoppedCounter == 0)
qDebug() << "Scene play/stop Button checked false" << endl;
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(false);

editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(false);



void Scene::playerStateChanged(QMediaPlayer::State state)
qDebug() << endl << "Player stateChanged() Emited!";
if(state == QMediaPlayer::State::PlayingState)
++stoppedCounter;
qDebug() << "Counter ++: " << stoppedCounter << endl;
else
--stoppedCounter;
qDebug() << "Counter --: " << stoppedCounter << endl;

soundEnd();


void Scene::loopScene(bool checked)
for(int i = 0; i < players.size(); ++i)
players.at(i)->getLoopButton()->setChecked(checked);
players.at(i)->loop(checked);



void Scene::playStop(bool checked)
if(checked)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/stop.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/stop.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(false);
players.at(i)->getPlayStopButton()->setChecked(false);



/* Los toca todos */
for(int i = 0; i < players.size(); ++i)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);

else
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);





void Scene::removeAllSounds(bool checked)
(void)checked;

for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
col = 0;
row = 0;
stoppedCounter = 0;


void Scene::removeSound(Player *player)
players.removeAll(player);

if(player->getPlayer()->PlayingState == QMediaPlayer::PlayingState)
--stoppedCounter;


player->~Player();

grid->~QGridLayout();
grid = new QGridLayout;
h->insertLayout(h->count() - 1, grid);

row = 0;
col = 0;
int counter = 0;
while(counter < players.size())
if(col < 3)
grid->addWidget(players.at(counter), row, col);
++col;
else
col = 0;
++row;
grid->addWidget(players.at(counter), row, col);
++col;

++counter;

soundEnd();


void Scene::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(col < 3)
appendSound(fileList, i);
++col;
else
col = 0;
row++;
appendSound(fileList, i);
++col;


else
return;



void Scene::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void Scene::setEditorLayout()
col = 0;
row = 0;

CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



editor = new Editor(this);
// editor->setScene(this);
editor->setWindowFlags(Qt::Window);
editor->setWindowModality(Qt::WindowModal);
editor->setAcceptDrops(true);

connect(listWidget, &CustomListWidget::customItem, editor, &Editor::addDefaultSound);

panel = new QWidget;

add = new QPushButton;
stopAll = new QPushButton;
removeAll = new QPushButton;
editorPS = new QPushButton;
editorPS->setCheckable(true);

add->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
add->setStyleSheet("background-color: transparent;");
add->setIcon(QIcon(QPixmap(":icons/add.png")));
add->setIconSize(QSize(38, 38));
add->setToolTip("Add Mp3 Sound");
add->setToolTipDuration(500);

stopAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAll->setStyleSheet("background-color: transparent;");
stopAll->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAll->setIconSize(QSize(38, 38));
stopAll->setToolTip("Stop All Sounds");
stopAll->setToolTipDuration(500);

removeAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAll->setStyleSheet("background-color: transparent;");
removeAll->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAll->setIconSize(QSize(38, 38));
removeAll->setToolTip("Remove All Sounds");
removeAll->setToolTipDuration(500);

editorPS->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
editorPS->setStyleSheet("background-color: transparent;");
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setIconSize(QSize(28, 28));
editorPS->setToolTip("Play / Stop All Sounds");
editorPS->setToolTipDuration(500);

grid = new QGridLayout;
panelLayout = new QHBoxLayout;
h = new QHBoxLayout;
v = new QVBoxLayout;

panelLayout->addWidget(add);
panelLayout->addWidget(stopAll);
panelLayout->addWidget(removeAll);
panelLayout->addWidget(editorPS);
panelLayout->addStretch(1);

panel->setLayout(panelLayout);

h->addLayout(grid);
h->addStretch(1);

v->addWidget(panel);
v->addLayout(h);
v->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(v);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

editor->setLayout(finalLayout);


void Scene::showEditor(bool checked)
(void)checked;

editor->setWindowTitle("Ambience Editor: " + ui->titleLabel->text());
editor->resize(400, 300);
editor->show();


void Scene::emitThisScene(bool checked)
(void)checked;
emit thisScene(this);


void Scene::setTitle(QString title)
ui->titleLabel->setText(title);


QPushButton* Scene::getPlayStopButton()
return ui->playStopButton;


void Scene::appendSound(QStringList list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &Scene::removeSound);
connect(players.at(players.size() - 1), &Player::sliderValueChanged, this, &Scene::setMasterVolume);

/* La conexion garantiza que si no hay ningun sonido en loop dentro del editor, el boton
* de play de la Scene cambie de estado */

connect(players.at(players.size() - 1)->getPlayer(), &QMediaPlayer::stateChanged,
this, &Scene::playerStateChanged);

qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
grid->addWidget(players.at(players.size() - 1), row, col);



widget.cpp



#include "widget.h"
#include "ui_widget.h"

#include "customtabwidget.h"

#include <QHBoxLayout>

#include <QDir>
#include <QFileInfoList>

Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);

QHBoxLayout *layout = new QHBoxLayout(this);

CustomTabWidget *tabWidget = new CustomTabWidget;

layout->addWidget(tabWidget);

this->setWindowTitle("TableTop SoundBoard v2.0");
this->resize(800, 600);


Widget::~Widget()
delete ui;







share|improve this question





















  • Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
    – yuri
    Apr 7 at 7:18










  • @yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
    – PVPJCJ
    Apr 7 at 14:44










  • A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
    – yuri
    Apr 7 at 15:14










  • @yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
    – PVPJCJ
    Apr 9 at 18:33

















up vote
4
down vote

favorite












I've been working on a soundboard software for tabletop games audio immersion in C++ using Qt. The software consists of 2 tabs who provides to a game master a set of individual sounds or scenes to be payed for a particular moment in the game.



The game master can choose the audio to play and the audio is embedded in a resource file from Qt. Besides taking almost 1.5 GB in ram (which have to be wrong), in general the software is running fine, the thing is for the past 2 weeks I feel like I'm not using C++ and Qt the way they are meant to. I'm just pretending to.



I try to come up with C++ 11, 14 and 17 as well as the "Qt way" standards to code (why I'm forced to create so many pointers: the compiler complains when I don't create one...) but it's just not as straightforward as I would like it to be. I want my code to be more elegant, more expressive, more verbose and efficient when running.



If anyone can take the time and point out where my weak spots are in general and what should be my thought process when writing code that would be of great help. If this is not the right place to ask for a code review of like this I'm sure you will point me out on the right direction.



.pro



QT += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SoundBoard
TEMPLATE = app

CONFIG += resources_big

RC_ICONS = Codex_book.ico

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES +=
main.cpp
widget.cpp
customlistwidget.cpp
customlistwidgetitem.cpp
customtabwidget.cpp
player.cpp
scene.cpp

HEADERS +=
widget.h
customlistwidget.h
customlistwidgetitem.h
customtabwidget.h
player.h
scene.h

FORMS +=
widget.ui
player.ui
scene.ui
player.ui

RESOURCES +=
src.qrc


Headers:



customlistwidget.h



#ifndef CUSTOMLISTWIDGET_H
#define CUSTOMLISTWIDGET_H

#include <QListWidget>
#include <QVector>

#include "customlistwidgetitem.h"

class CustomListWidget : public QListWidget
Q_OBJECT
public:
CustomListWidget(QWidget *parent = nullptr);

void addCustomItem(CustomListWidgetItem*);

public slots:
void setItemPressed(QListWidgetItem*);
void emitCustomItem(QListWidgetItem*);

signals:
void customItem(CustomListWidgetItem*);

protected:
void startDrag(Qt::DropActions supportedActions);

private:
QVector<CustomListWidgetItem*> list;
QListWidgetItem *itemToBeSet;
;

#endif // CUSTOMLISTWIDGET_H


customlistwidgetitem.h



#ifndef CUSTOMLISTWIDGETITEM_H
#define CUSTOMLISTWIDGETITEM_H

#include <QListWidgetItem>
#include <QFileInfo>

class CustomListWidgetItem : public QListWidgetItem
public:
CustomListWidgetItem(QFileInfo, QIcon, QListWidget *parent = nullptr);
~CustomListWidgetItem();

QFileInfo getFileInfo();

private:
QFileInfo fileInfo;
;

#endif // CUSTOMLISTWIDGETITEM_H


customtabwidget.h



#ifndef CUSTOMTABWIDGET_H
#define CUSTOMTABWIDGET_H

#include <QTabWidget>
#include <QWidget>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>

#include <QScrollArea>

#include <QPushButton>

#include <QVector>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "scene.h"
#include "player.h"
#include "customlistwidgetitem.h"

class CustomTabWidget : public QTabWidget
Q_OBJECT

public:
CustomTabWidget(QWidget *parent = nullptr);

void setSoundLayout();
void setSceneLayout();

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

public slots:
void addScene(bool);
void stopAllScenes(bool);
void removeScene(Scene*);
void removeAllScenes(bool);


void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player*);
void removeAllSounds(bool);

void addDefaultSound(CustomListWidgetItem*);

private:
void appendSound(QStringList &, int);
void appendScene(QString);

QVector<Scene*> scenes;
QVector<Player*> players;

QGridLayout *soundGrid;
QGridLayout *sceneGrid;

QWidget *soundPanel;
QWidget *scenePanel;

QHBoxLayout *soundPanelLayout;
QHBoxLayout *scenePanelLayout;

QHBoxLayout *hSoundLayout;
QVBoxLayout *vSoundLayout;

QHBoxLayout *hSceneLayout;
QVBoxLayout *vSceneLayout;

int soundCol;
int soundRow;

int sceneCol;
int sceneRow;

QPushButton *addSoundButton;
QPushButton *removeAllSoundsButton;
QPushButton *stopAllSoundsButton;

QPushButton *addSceneButton;
QPushButton *removeAllScenesButton;
QPushButton *stopAllScenesButton;

QScrollArea *scrollSound;
QScrollArea *scrollScene;

QWidget *soundScroll;
QWidget *sceneScroll;
;

#endif // CUSTOMTABWIDGET_H


player.h



#ifndef PLAYER_H
#define PLAYER_H

#include <QWidget>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QCheckBox>
#include <QPushButton>

namespace Ui
class Player;


class Player : public QWidget
Q_OBJECT

public:
explicit Player(QWidget *parent = 0);
~Player();

void setTitle(QString);
void setIconState(QString);

QMediaPlaylist *getPlaylist();
QMediaPlayer *getPlayer();
QCheckBox* getLoopButton();
QPushButton* getPlayStopButton();
float getSliderValue();

public slots:
void playStopButton(bool);
void soundEnd(QMediaPlayer::State);
void loop(bool);
void emitThisPlayer(bool);

signals:
void thisPlayer(Player*);
void stateChanged(QMediaPlayer::State);
void sliderValueChanged(int);

private:
Ui::Player *ui;

QMediaPlayer *mPlayer;
QMediaPlaylist *mPlaylist;

float volume;
;

#endif // PLAYER_H


scene.h



#ifndef SCENE_H
#define SCENE_H

#include <QWidget>
#include <QPushButton>
#include <QGridLayout>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "player.h"
#include "customlistwidget.h"

namespace Ui
class Scene;


class Scene;

class Editor : public QWidget
Q_OBJECT

public:
explicit Editor(Scene *parent = 0);
~Editor();

void addDefaultSound(CustomListWidgetItem*);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

void resizeEvent(QResizeEvent *evt);
void closeEvent(QCloseEvent *event);

signals:
void hidden(bool);

private:
Scene *scene;
;

class Scene : public QWidget
Q_OBJECT

public:
explicit Scene(QWidget *parent = 0);
~Scene();

void appendSound(QStringList, int);

int getCol();
void setCol(int);

int getRow();
void setRow(int);

void setTitle(QString);
QPushButton *getPlayStopButton();

public slots:
void emitThisScene(bool);
void showEditor(bool);
void playStop(bool);
void loopScene(bool);
void playerStateChanged(QMediaPlayer::State);
void soundEnd();
void masterVolume(int);
void setMasterVolume(int);

void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player *player);
void removeAllSounds(bool);

signals:
void thisScene(Scene*);

private:
void setEditorLayout();

Ui::Scene *ui;
QVector<Player*> players;

Editor *editor;

QPushButton *add;
QPushButton *stopAll;
QPushButton *removeAll;
QPushButton *editorPS;

QGridLayout *grid;
QWidget *panel;

QHBoxLayout *h;
QVBoxLayout *v;

QHBoxLayout *panelLayout;

int col;
int row;

int stoppedCounter;
;

#endif // SCENE_H


widget.h



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui
class Widget;


class Widget : public QWidget
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
;

#endif // WIDGET_H


Sources:



customlistwidget.cpp



#include "customlistwidget.h"

#include <QMouseEvent>

#include <QMimeData>
#include <QDrag>

#include <QList>
#include <QUrl>

#include <QByteArray>

#include <QDebug>

CustomListWidget::CustomListWidget(QWidget *parent) : QListWidget(parent)

setMouseTracking(true);

setDragEnabled(true);
setDragDropMode(QListWidget::DragOnly);

connect(this, &CustomListWidget::itemEntered, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemClicked, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemDoubleClicked, this, &CustomListWidget::emitCustomItem);
itemToBeSet = nullptr;

setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);


void CustomListWidget::addCustomItem(CustomListWidgetItem *customItem)
list.push_back(customItem);
qDebug() << "Custom Item Added: " << list.size() << endl;
QListWidgetItem *item = new QListWidgetItem(this);
item->setText(customItem->text());
item->setIcon(customItem->icon());


void CustomListWidget::setItemPressed(QListWidgetItem *item)
itemToBeSet = item;
qDebug() << "set" << endl;


void CustomListWidget::emitCustomItem(QListWidgetItem *item)
for(int i = 0; i < list.size(); ++i)
if(item->text() == list.at(i)->getFileInfo().baseName())
emit customItem(list.at(i));




void CustomListWidget::startDrag(Qt::DropActions supportedActions)
(void)supportedActions;
QList<QUrl> url;

QByteArray ba;

QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;

if(itemToBeSet)
for(int i = 0; i < list.size(); ++i)
if(itemToBeSet->text() == list.at(i)->text())
ba.append(list.at(i)->getFileInfo().absoluteFilePath());




mimeData->setData("FileInfo", ba);

drag->setMimeData(mimeData);
drag->exec();



customlistwidgetitem.cpp



#include "customlistwidgetitem.h"

#include <QDebug>

CustomListWidgetItem::CustomListWidgetItem(QFileInfo infoFile, QIcon icon, QListWidget *parent)
: QListWidgetItem(parent)

fileInfo = infoFile;

setText(infoFile.baseName());
setIcon(icon);


CustomListWidgetItem::~CustomListWidgetItem()
delete &fileInfo;


QFileInfo CustomListWidgetItem::getFileInfo()
return fileInfo;



customtabwidget.cpp



#include "customtabwidget.h"

#include "customlistwidget.h"

#include <QMimeData>

#include <QFileDialog>
#include <QInputDialog>

CustomTabWidget::CustomTabWidget(QWidget *parent) : QTabWidget(parent)

scrollSound = new QScrollArea(this);
soundScroll = new QWidget(scrollSound);
soundScroll->setStyleSheet("background-image: url(:/images/Listen.png");

scrollSound->setWidgetResizable(true);
soundScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSoundLayout();

scrollScene = new QScrollArea(this);
sceneScroll = new QWidget(scrollScene);
scrollScene->setWidgetResizable(true);
sceneScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSceneLayout();

scrollSound->setWidget(soundScroll);
scrollScene->setWidget(sceneScroll);

addTab(scrollSound, "Sounds");
addTab(scrollScene, "Ambience");

setAcceptDrops(true);

connect(addSoundButton, &QPushButton::clicked, this, &CustomTabWidget::addSound);
connect(stopAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllSounds);
connect(removeAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllSounds);

connect(addSceneButton, &QPushButton::clicked, this, &CustomTabWidget::addScene);
connect(stopAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllScenes);
connect(removeAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllScenes);


void CustomTabWidget::setSoundLayout()
CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



connect(listWidget, &CustomListWidget::customItem, this, &CustomTabWidget::addDefaultSound);

soundCol = 0;
soundRow = 0;

addSoundButton = new QPushButton;
stopAllSoundsButton = new QPushButton;
removeAllSoundsButton = new QPushButton;

addSoundButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSoundButton->setStyleSheet("background-color: transparent;");
addSoundButton->setIcon(QIcon(QPixmap(":icons/add.png")));
addSoundButton->setIconSize(QSize(38, 38));
addSoundButton->setToolTip("Add Mp3 Track");
addSoundButton->setToolTipDuration(1000);

stopAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllSoundsButton->setStyleSheet("background-color: transparent;");
stopAllSoundsButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllSoundsButton->setIconSize(QSize(38, 38));
stopAllSoundsButton->setToolTip("Stop All Tracks");
stopAllSoundsButton->setToolTipDuration(1000);

removeAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllSoundsButton->setStyleSheet("background-color: transparent;");
removeAllSoundsButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllSoundsButton->setIconSize(QSize(38, 38));
removeAllSoundsButton->setToolTip("Remove All Tracks");
removeAllSoundsButton->setToolTipDuration(1000);

soundPanel = new QWidget;
soundPanelLayout = new QHBoxLayout;

soundGrid = new QGridLayout;

hSoundLayout = new QHBoxLayout;
vSoundLayout = new QVBoxLayout;

soundPanelLayout->addWidget(addSoundButton);
soundPanelLayout->addWidget(stopAllSoundsButton);
soundPanelLayout->addWidget(removeAllSoundsButton);
soundPanelLayout->addStretch(1);

soundPanel->setLayout(soundPanelLayout);

hSoundLayout->addLayout(soundGrid);
hSoundLayout->addStretch(1);

vSoundLayout->addWidget(soundPanel);
vSoundLayout->addLayout(hSoundLayout);
vSoundLayout->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(vSoundLayout);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

soundScroll->setLayout(finalLayout);


void CustomTabWidget::setSceneLayout()
sceneCol = 0;
sceneRow = 0;

addSceneButton = new QPushButton;
stopAllScenesButton = new QPushButton;
removeAllScenesButton = new QPushButton;

addSceneButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSceneButton->setStyleSheet("background-color: transparent;");
addSceneButton->setIcon(QIcon(QPixmap(":icons/scene.png")));
addSceneButton->setIconSize(QSize(38, 38));
addSceneButton->setToolTip("Add Mp3 Track");
addSceneButton->setToolTipDuration(1000);

stopAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllScenesButton->setStyleSheet("background-color: transparent;");
stopAllScenesButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllScenesButton->setIconSize(QSize(38, 38));
stopAllScenesButton->setToolTip("Stop All Tracks");
stopAllScenesButton->setToolTipDuration(1000);

removeAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllScenesButton->setStyleSheet("background-color: transparent;");
removeAllScenesButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllScenesButton->setIconSize(QSize(38, 38));
removeAllScenesButton->setToolTip("Remove All Tracks");
removeAllScenesButton->setToolTipDuration(1000);

sceneGrid = new QGridLayout;
scenePanel = new QWidget;
scenePanelLayout = new QHBoxLayout;
hSceneLayout = new QHBoxLayout;
vSceneLayout = new QVBoxLayout;
sceneScroll->setLayout(vSceneLayout);

scenePanelLayout->addWidget(addSceneButton);
scenePanelLayout->addWidget(stopAllScenesButton);
scenePanelLayout->addWidget(removeAllScenesButton);

scenePanelLayout->addStretch(1);

scenePanel->setLayout(scenePanelLayout);

hSceneLayout->addLayout(sceneGrid);
hSceneLayout->addStretch(1);

vSceneLayout->addWidget(scenePanel);
vSceneLayout->addLayout(hSceneLayout);
vSceneLayout->addStretch(1);


void CustomTabWidget::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void CustomTabWidget::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dropEvent(QDropEvent *event)
QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(soundCol < 3)
appendSound(fileList, i);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(fileList, i);
++soundCol;


else
return;



void CustomTabWidget::removeSound(Player *player)
players.removeAll(player);
player->~Player();

soundGrid->~QGridLayout();
soundGrid = new QGridLayout;
hSoundLayout->insertLayout(hSoundLayout->count() - 1, soundGrid);

soundRow = 0;
soundCol = 0;
int counter = 0;
while(counter < players.size())
if(soundCol < 3)
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;
else
soundCol = 0;
++soundRow;
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;

++counter;



void CustomTabWidget::removeAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
soundCol = 0;
soundRow = 0;


void CustomTabWidget::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void CustomTabWidget::addScene(bool checked)
(void)checked;

bool ok;
QString title = QInputDialog::getText(this, "Scene Title",
"Title: ", QLineEdit::Normal,
"", &ok);
if (ok && !title.isEmpty())
if(sceneCol < 5)
appendScene(title);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
appendScene(title);
++sceneCol;

else
return;



void CustomTabWidget::stopAllScenes(bool checked)
(void)checked;
for(int i = 0; i < scenes.size(); ++i)
if(scenes.at(i)->getPlayStopButton()->isChecked())
scenes.at(i)->playStop(false);
scenes.at(i)->getPlayStopButton()->setChecked(false);
// scenes.at(i)->getPlayStopButton()->click();




void CustomTabWidget::removeScene(Scene *scene)
scenes.removeAll(scene);
scene->~Scene();

sceneGrid->~QGridLayout();
sceneGrid = new QGridLayout;
hSceneLayout->insertLayout(hSceneLayout->count() - 1, sceneGrid);

sceneRow = 0;
sceneCol = 0;
int counter = 0;
while(counter < scenes.size())
if(sceneCol < 5)
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;

++counter;



void CustomTabWidget::removeAllScenes(bool checked)
(void)checked;

for(int i = 0; i < scenes.size(); ++i)
scenes.at(i)->~Scene();

scenes.clear();
sceneCol = 0;
sceneRow = 0;


void CustomTabWidget::appendSound(QStringList &list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &CustomTabWidget::removeSound);
qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
qDebug() << file << endl;
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
soundGrid->addWidget(players.at(players.size() - 1), soundRow, soundCol);


void CustomTabWidget::appendScene(QString title)
Scene *scene = new Scene;
connect(scene, &Scene::thisScene, this, &CustomTabWidget::removeScene);
scenes.append(scene);
scene->setTitle(title);
sceneGrid->addWidget(scene, sceneRow, sceneCol);



main.cpp



#include "widget.h"
#include <QApplication>

int main(int argc, char *argv)
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();



player.cpp



#include "player.h"
#include "ui_player.h"

#include <QPainter>

Player::Player(QWidget *parent) : QWidget(parent),
ui(new Ui::Player)
ui->setupUi(this);

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setValue(50);
ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);

ui->deleteButton->setToolTip("Delete");
ui->deleteButton->setToolTipDuration(500);


mPlayer = new QMediaPlayer(this);
mPlaylist = new QMediaPlaylist(this);
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
mPlayer->setPlaylist(mPlaylist);
mPlayer->setVolume(ui->volumeSlider->value());

connect(ui->playStopButton, &QPushButton::clicked, this, &Player::playStopButton);
connect(ui->deleteButton, &QPushButton::clicked, this, &Player::emitThisPlayer);
connect(mPlayer, &QMediaPlayer::stateChanged, this, &Player::soundEnd);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Player::loop);
connect(ui->volumeSlider, &QSlider::valueChanged, mPlayer, &QMediaPlayer::setVolume);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Player::sliderValueChanged);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
setIconState("play");
ui->playStopButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Player::~Player()
delete ui;


void Player::loop(bool checked)
if(checked)
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
else
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);



void Player::soundEnd(QMediaPlayer::State state)
if(state == QMediaPlayer::State::StoppedState)
setIconState("play");
ui->playStopButton->setChecked(false);



void Player::playStopButton(bool checked)
if(checked)
setIconState("stop");
mPlayer->play();
else
setIconState("play");
if(mPlayer->state() == QMediaPlayer::State::PlayingState)
mPlayer->stop();
else
return;




void Player::setTitle(QString title)
ui->titleLabel->setText(title);


void Player::setIconState(QString str)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/" + str + ".png")));


float Player::getSliderValue()
return (float)ui->volumeSlider->value();


QPushButton* Player::getPlayStopButton()
return ui->playStopButton;


QCheckBox* Player::getLoopButton()
return ui->loopCheckBox;


QMediaPlayer *Player::getPlayer()
return mPlayer;


QMediaPlaylist *Player::getPlaylist()
return mPlaylist;


void Player::emitThisPlayer(bool checked)
(void)checked;
emit thisPlayer(this);



scene.cpp



#include "scene.h"
#include "ui_scene.h"

#include <QFileDialog>
#include <QCloseEvent>

#include <QStringList>
#include <QMimeData>

Scene::Scene(QWidget *parent) : QWidget(parent),
ui(new Ui::Scene)
ui->setupUi(this);

stoppedCounter = 0;

setEditorLayout();

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);
ui->volumeSlider->setValue(50);

ui->deleteButton->setToolTip("Delete Scene");
ui->deleteButton->setToolTipDuration(500);

connect(ui->playStopButton, &QPushButton::clicked, this, &Scene::playStop);
connect(ui->editorButton, &QPushButton::clicked, this, &Scene::showEditor);
connect(ui->deleteButton, &QPushButton::clicked, this, &Scene::emitThisScene);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Scene::loopScene);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Scene::masterVolume);

connect(add, &QPushButton::clicked, this, &Scene::addSound);
connect(stopAll, &QPushButton::clicked, this, &Scene::stopAllSounds);
connect(removeAll, &QPushButton::clicked, this, &Scene::removeAllSounds);
connect(editorPS, &QPushButton::clicked, this, &Scene::playStop);
// connect(editor, &Editor::hidden, this, &Scene::playStop);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setIconSize(QSize(28, 28));

ui->editorButton->setStyleSheet("background-color: transparent;");
ui->editorButton->setIcon(QIcon(QPixmap(":/icons/settings.png")));
ui->editorButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Scene::~Scene()
delete ui;


void Editor::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void Editor::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void Editor::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void Editor::dropEvent(QDropEvent *event)

QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



void Editor::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



int Scene::getCol()
return col;


void Scene::setCol(int i)
col = i;


int Scene::getRow()
return row;


void Scene::setRow(int i)
row = i;


Editor::Editor(Scene *parent) : QWidget(parent)
scene = parent;


void Editor::resizeEvent(QResizeEvent *evt)
QPixmap bkgnd(":/images/library wizard.jpg");
bkgnd = bkgnd.scaled(size(), Qt::IgnoreAspectRatio);
QPalette p = palette(); //copy current, not create new
p.setBrush(QPalette::Background, bkgnd);
setPalette(p);

QWidget::resizeEvent(evt); //call base implementation


void Editor::closeEvent(QCloseEvent *event)
event->ignore();
scene->stopAllSounds(true);
this->hide();

// emit hidden(false);


Editor::~Editor()



void Scene::masterVolume(int i)
for(int j = 0; j < players.size(); ++j)
players.at(j)->getPlayer()->setVolume((players.at(j)->getSliderValue() / 100) * i);



void Scene::setMasterVolume(int i)
(void)i;
masterVolume(ui->volumeSlider->value());


void Scene::soundEnd()
qDebug() << endl << "soundEnd() Emitido";
if(stoppedCounter == 0)
qDebug() << "Scene play/stop Button checked false" << endl;
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(false);

editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(false);



void Scene::playerStateChanged(QMediaPlayer::State state)
qDebug() << endl << "Player stateChanged() Emited!";
if(state == QMediaPlayer::State::PlayingState)
++stoppedCounter;
qDebug() << "Counter ++: " << stoppedCounter << endl;
else
--stoppedCounter;
qDebug() << "Counter --: " << stoppedCounter << endl;

soundEnd();


void Scene::loopScene(bool checked)
for(int i = 0; i < players.size(); ++i)
players.at(i)->getLoopButton()->setChecked(checked);
players.at(i)->loop(checked);



void Scene::playStop(bool checked)
if(checked)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/stop.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/stop.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(false);
players.at(i)->getPlayStopButton()->setChecked(false);



/* Los toca todos */
for(int i = 0; i < players.size(); ++i)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);

else
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);





void Scene::removeAllSounds(bool checked)
(void)checked;

for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
col = 0;
row = 0;
stoppedCounter = 0;


void Scene::removeSound(Player *player)
players.removeAll(player);

if(player->getPlayer()->PlayingState == QMediaPlayer::PlayingState)
--stoppedCounter;


player->~Player();

grid->~QGridLayout();
grid = new QGridLayout;
h->insertLayout(h->count() - 1, grid);

row = 0;
col = 0;
int counter = 0;
while(counter < players.size())
if(col < 3)
grid->addWidget(players.at(counter), row, col);
++col;
else
col = 0;
++row;
grid->addWidget(players.at(counter), row, col);
++col;

++counter;

soundEnd();


void Scene::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(col < 3)
appendSound(fileList, i);
++col;
else
col = 0;
row++;
appendSound(fileList, i);
++col;


else
return;



void Scene::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void Scene::setEditorLayout()
col = 0;
row = 0;

CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



editor = new Editor(this);
// editor->setScene(this);
editor->setWindowFlags(Qt::Window);
editor->setWindowModality(Qt::WindowModal);
editor->setAcceptDrops(true);

connect(listWidget, &CustomListWidget::customItem, editor, &Editor::addDefaultSound);

panel = new QWidget;

add = new QPushButton;
stopAll = new QPushButton;
removeAll = new QPushButton;
editorPS = new QPushButton;
editorPS->setCheckable(true);

add->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
add->setStyleSheet("background-color: transparent;");
add->setIcon(QIcon(QPixmap(":icons/add.png")));
add->setIconSize(QSize(38, 38));
add->setToolTip("Add Mp3 Sound");
add->setToolTipDuration(500);

stopAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAll->setStyleSheet("background-color: transparent;");
stopAll->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAll->setIconSize(QSize(38, 38));
stopAll->setToolTip("Stop All Sounds");
stopAll->setToolTipDuration(500);

removeAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAll->setStyleSheet("background-color: transparent;");
removeAll->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAll->setIconSize(QSize(38, 38));
removeAll->setToolTip("Remove All Sounds");
removeAll->setToolTipDuration(500);

editorPS->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
editorPS->setStyleSheet("background-color: transparent;");
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setIconSize(QSize(28, 28));
editorPS->setToolTip("Play / Stop All Sounds");
editorPS->setToolTipDuration(500);

grid = new QGridLayout;
panelLayout = new QHBoxLayout;
h = new QHBoxLayout;
v = new QVBoxLayout;

panelLayout->addWidget(add);
panelLayout->addWidget(stopAll);
panelLayout->addWidget(removeAll);
panelLayout->addWidget(editorPS);
panelLayout->addStretch(1);

panel->setLayout(panelLayout);

h->addLayout(grid);
h->addStretch(1);

v->addWidget(panel);
v->addLayout(h);
v->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(v);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

editor->setLayout(finalLayout);


void Scene::showEditor(bool checked)
(void)checked;

editor->setWindowTitle("Ambience Editor: " + ui->titleLabel->text());
editor->resize(400, 300);
editor->show();


void Scene::emitThisScene(bool checked)
(void)checked;
emit thisScene(this);


void Scene::setTitle(QString title)
ui->titleLabel->setText(title);


QPushButton* Scene::getPlayStopButton()
return ui->playStopButton;


void Scene::appendSound(QStringList list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &Scene::removeSound);
connect(players.at(players.size() - 1), &Player::sliderValueChanged, this, &Scene::setMasterVolume);

/* La conexion garantiza que si no hay ningun sonido en loop dentro del editor, el boton
* de play de la Scene cambie de estado */

connect(players.at(players.size() - 1)->getPlayer(), &QMediaPlayer::stateChanged,
this, &Scene::playerStateChanged);

qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
grid->addWidget(players.at(players.size() - 1), row, col);



widget.cpp



#include "widget.h"
#include "ui_widget.h"

#include "customtabwidget.h"

#include <QHBoxLayout>

#include <QDir>
#include <QFileInfoList>

Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);

QHBoxLayout *layout = new QHBoxLayout(this);

CustomTabWidget *tabWidget = new CustomTabWidget;

layout->addWidget(tabWidget);

this->setWindowTitle("TableTop SoundBoard v2.0");
this->resize(800, 600);


Widget::~Widget()
delete ui;







share|improve this question





















  • Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
    – yuri
    Apr 7 at 7:18










  • @yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
    – PVPJCJ
    Apr 7 at 14:44










  • A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
    – yuri
    Apr 7 at 15:14










  • @yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
    – PVPJCJ
    Apr 9 at 18:33













up vote
4
down vote

favorite









up vote
4
down vote

favorite











I've been working on a soundboard software for tabletop games audio immersion in C++ using Qt. The software consists of 2 tabs who provides to a game master a set of individual sounds or scenes to be payed for a particular moment in the game.



The game master can choose the audio to play and the audio is embedded in a resource file from Qt. Besides taking almost 1.5 GB in ram (which have to be wrong), in general the software is running fine, the thing is for the past 2 weeks I feel like I'm not using C++ and Qt the way they are meant to. I'm just pretending to.



I try to come up with C++ 11, 14 and 17 as well as the "Qt way" standards to code (why I'm forced to create so many pointers: the compiler complains when I don't create one...) but it's just not as straightforward as I would like it to be. I want my code to be more elegant, more expressive, more verbose and efficient when running.



If anyone can take the time and point out where my weak spots are in general and what should be my thought process when writing code that would be of great help. If this is not the right place to ask for a code review of like this I'm sure you will point me out on the right direction.



.pro



QT += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SoundBoard
TEMPLATE = app

CONFIG += resources_big

RC_ICONS = Codex_book.ico

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES +=
main.cpp
widget.cpp
customlistwidget.cpp
customlistwidgetitem.cpp
customtabwidget.cpp
player.cpp
scene.cpp

HEADERS +=
widget.h
customlistwidget.h
customlistwidgetitem.h
customtabwidget.h
player.h
scene.h

FORMS +=
widget.ui
player.ui
scene.ui
player.ui

RESOURCES +=
src.qrc


Headers:



customlistwidget.h



#ifndef CUSTOMLISTWIDGET_H
#define CUSTOMLISTWIDGET_H

#include <QListWidget>
#include <QVector>

#include "customlistwidgetitem.h"

class CustomListWidget : public QListWidget
Q_OBJECT
public:
CustomListWidget(QWidget *parent = nullptr);

void addCustomItem(CustomListWidgetItem*);

public slots:
void setItemPressed(QListWidgetItem*);
void emitCustomItem(QListWidgetItem*);

signals:
void customItem(CustomListWidgetItem*);

protected:
void startDrag(Qt::DropActions supportedActions);

private:
QVector<CustomListWidgetItem*> list;
QListWidgetItem *itemToBeSet;
;

#endif // CUSTOMLISTWIDGET_H


customlistwidgetitem.h



#ifndef CUSTOMLISTWIDGETITEM_H
#define CUSTOMLISTWIDGETITEM_H

#include <QListWidgetItem>
#include <QFileInfo>

class CustomListWidgetItem : public QListWidgetItem
public:
CustomListWidgetItem(QFileInfo, QIcon, QListWidget *parent = nullptr);
~CustomListWidgetItem();

QFileInfo getFileInfo();

private:
QFileInfo fileInfo;
;

#endif // CUSTOMLISTWIDGETITEM_H


customtabwidget.h



#ifndef CUSTOMTABWIDGET_H
#define CUSTOMTABWIDGET_H

#include <QTabWidget>
#include <QWidget>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>

#include <QScrollArea>

#include <QPushButton>

#include <QVector>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "scene.h"
#include "player.h"
#include "customlistwidgetitem.h"

class CustomTabWidget : public QTabWidget
Q_OBJECT

public:
CustomTabWidget(QWidget *parent = nullptr);

void setSoundLayout();
void setSceneLayout();

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

public slots:
void addScene(bool);
void stopAllScenes(bool);
void removeScene(Scene*);
void removeAllScenes(bool);


void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player*);
void removeAllSounds(bool);

void addDefaultSound(CustomListWidgetItem*);

private:
void appendSound(QStringList &, int);
void appendScene(QString);

QVector<Scene*> scenes;
QVector<Player*> players;

QGridLayout *soundGrid;
QGridLayout *sceneGrid;

QWidget *soundPanel;
QWidget *scenePanel;

QHBoxLayout *soundPanelLayout;
QHBoxLayout *scenePanelLayout;

QHBoxLayout *hSoundLayout;
QVBoxLayout *vSoundLayout;

QHBoxLayout *hSceneLayout;
QVBoxLayout *vSceneLayout;

int soundCol;
int soundRow;

int sceneCol;
int sceneRow;

QPushButton *addSoundButton;
QPushButton *removeAllSoundsButton;
QPushButton *stopAllSoundsButton;

QPushButton *addSceneButton;
QPushButton *removeAllScenesButton;
QPushButton *stopAllScenesButton;

QScrollArea *scrollSound;
QScrollArea *scrollScene;

QWidget *soundScroll;
QWidget *sceneScroll;
;

#endif // CUSTOMTABWIDGET_H


player.h



#ifndef PLAYER_H
#define PLAYER_H

#include <QWidget>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QCheckBox>
#include <QPushButton>

namespace Ui
class Player;


class Player : public QWidget
Q_OBJECT

public:
explicit Player(QWidget *parent = 0);
~Player();

void setTitle(QString);
void setIconState(QString);

QMediaPlaylist *getPlaylist();
QMediaPlayer *getPlayer();
QCheckBox* getLoopButton();
QPushButton* getPlayStopButton();
float getSliderValue();

public slots:
void playStopButton(bool);
void soundEnd(QMediaPlayer::State);
void loop(bool);
void emitThisPlayer(bool);

signals:
void thisPlayer(Player*);
void stateChanged(QMediaPlayer::State);
void sliderValueChanged(int);

private:
Ui::Player *ui;

QMediaPlayer *mPlayer;
QMediaPlaylist *mPlaylist;

float volume;
;

#endif // PLAYER_H


scene.h



#ifndef SCENE_H
#define SCENE_H

#include <QWidget>
#include <QPushButton>
#include <QGridLayout>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "player.h"
#include "customlistwidget.h"

namespace Ui
class Scene;


class Scene;

class Editor : public QWidget
Q_OBJECT

public:
explicit Editor(Scene *parent = 0);
~Editor();

void addDefaultSound(CustomListWidgetItem*);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

void resizeEvent(QResizeEvent *evt);
void closeEvent(QCloseEvent *event);

signals:
void hidden(bool);

private:
Scene *scene;
;

class Scene : public QWidget
Q_OBJECT

public:
explicit Scene(QWidget *parent = 0);
~Scene();

void appendSound(QStringList, int);

int getCol();
void setCol(int);

int getRow();
void setRow(int);

void setTitle(QString);
QPushButton *getPlayStopButton();

public slots:
void emitThisScene(bool);
void showEditor(bool);
void playStop(bool);
void loopScene(bool);
void playerStateChanged(QMediaPlayer::State);
void soundEnd();
void masterVolume(int);
void setMasterVolume(int);

void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player *player);
void removeAllSounds(bool);

signals:
void thisScene(Scene*);

private:
void setEditorLayout();

Ui::Scene *ui;
QVector<Player*> players;

Editor *editor;

QPushButton *add;
QPushButton *stopAll;
QPushButton *removeAll;
QPushButton *editorPS;

QGridLayout *grid;
QWidget *panel;

QHBoxLayout *h;
QVBoxLayout *v;

QHBoxLayout *panelLayout;

int col;
int row;

int stoppedCounter;
;

#endif // SCENE_H


widget.h



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui
class Widget;


class Widget : public QWidget
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
;

#endif // WIDGET_H


Sources:



customlistwidget.cpp



#include "customlistwidget.h"

#include <QMouseEvent>

#include <QMimeData>
#include <QDrag>

#include <QList>
#include <QUrl>

#include <QByteArray>

#include <QDebug>

CustomListWidget::CustomListWidget(QWidget *parent) : QListWidget(parent)

setMouseTracking(true);

setDragEnabled(true);
setDragDropMode(QListWidget::DragOnly);

connect(this, &CustomListWidget::itemEntered, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemClicked, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemDoubleClicked, this, &CustomListWidget::emitCustomItem);
itemToBeSet = nullptr;

setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);


void CustomListWidget::addCustomItem(CustomListWidgetItem *customItem)
list.push_back(customItem);
qDebug() << "Custom Item Added: " << list.size() << endl;
QListWidgetItem *item = new QListWidgetItem(this);
item->setText(customItem->text());
item->setIcon(customItem->icon());


void CustomListWidget::setItemPressed(QListWidgetItem *item)
itemToBeSet = item;
qDebug() << "set" << endl;


void CustomListWidget::emitCustomItem(QListWidgetItem *item)
for(int i = 0; i < list.size(); ++i)
if(item->text() == list.at(i)->getFileInfo().baseName())
emit customItem(list.at(i));




void CustomListWidget::startDrag(Qt::DropActions supportedActions)
(void)supportedActions;
QList<QUrl> url;

QByteArray ba;

QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;

if(itemToBeSet)
for(int i = 0; i < list.size(); ++i)
if(itemToBeSet->text() == list.at(i)->text())
ba.append(list.at(i)->getFileInfo().absoluteFilePath());




mimeData->setData("FileInfo", ba);

drag->setMimeData(mimeData);
drag->exec();



customlistwidgetitem.cpp



#include "customlistwidgetitem.h"

#include <QDebug>

CustomListWidgetItem::CustomListWidgetItem(QFileInfo infoFile, QIcon icon, QListWidget *parent)
: QListWidgetItem(parent)

fileInfo = infoFile;

setText(infoFile.baseName());
setIcon(icon);


CustomListWidgetItem::~CustomListWidgetItem()
delete &fileInfo;


QFileInfo CustomListWidgetItem::getFileInfo()
return fileInfo;



customtabwidget.cpp



#include "customtabwidget.h"

#include "customlistwidget.h"

#include <QMimeData>

#include <QFileDialog>
#include <QInputDialog>

CustomTabWidget::CustomTabWidget(QWidget *parent) : QTabWidget(parent)

scrollSound = new QScrollArea(this);
soundScroll = new QWidget(scrollSound);
soundScroll->setStyleSheet("background-image: url(:/images/Listen.png");

scrollSound->setWidgetResizable(true);
soundScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSoundLayout();

scrollScene = new QScrollArea(this);
sceneScroll = new QWidget(scrollScene);
scrollScene->setWidgetResizable(true);
sceneScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSceneLayout();

scrollSound->setWidget(soundScroll);
scrollScene->setWidget(sceneScroll);

addTab(scrollSound, "Sounds");
addTab(scrollScene, "Ambience");

setAcceptDrops(true);

connect(addSoundButton, &QPushButton::clicked, this, &CustomTabWidget::addSound);
connect(stopAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllSounds);
connect(removeAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllSounds);

connect(addSceneButton, &QPushButton::clicked, this, &CustomTabWidget::addScene);
connect(stopAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllScenes);
connect(removeAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllScenes);


void CustomTabWidget::setSoundLayout()
CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



connect(listWidget, &CustomListWidget::customItem, this, &CustomTabWidget::addDefaultSound);

soundCol = 0;
soundRow = 0;

addSoundButton = new QPushButton;
stopAllSoundsButton = new QPushButton;
removeAllSoundsButton = new QPushButton;

addSoundButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSoundButton->setStyleSheet("background-color: transparent;");
addSoundButton->setIcon(QIcon(QPixmap(":icons/add.png")));
addSoundButton->setIconSize(QSize(38, 38));
addSoundButton->setToolTip("Add Mp3 Track");
addSoundButton->setToolTipDuration(1000);

stopAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllSoundsButton->setStyleSheet("background-color: transparent;");
stopAllSoundsButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllSoundsButton->setIconSize(QSize(38, 38));
stopAllSoundsButton->setToolTip("Stop All Tracks");
stopAllSoundsButton->setToolTipDuration(1000);

removeAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllSoundsButton->setStyleSheet("background-color: transparent;");
removeAllSoundsButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllSoundsButton->setIconSize(QSize(38, 38));
removeAllSoundsButton->setToolTip("Remove All Tracks");
removeAllSoundsButton->setToolTipDuration(1000);

soundPanel = new QWidget;
soundPanelLayout = new QHBoxLayout;

soundGrid = new QGridLayout;

hSoundLayout = new QHBoxLayout;
vSoundLayout = new QVBoxLayout;

soundPanelLayout->addWidget(addSoundButton);
soundPanelLayout->addWidget(stopAllSoundsButton);
soundPanelLayout->addWidget(removeAllSoundsButton);
soundPanelLayout->addStretch(1);

soundPanel->setLayout(soundPanelLayout);

hSoundLayout->addLayout(soundGrid);
hSoundLayout->addStretch(1);

vSoundLayout->addWidget(soundPanel);
vSoundLayout->addLayout(hSoundLayout);
vSoundLayout->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(vSoundLayout);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

soundScroll->setLayout(finalLayout);


void CustomTabWidget::setSceneLayout()
sceneCol = 0;
sceneRow = 0;

addSceneButton = new QPushButton;
stopAllScenesButton = new QPushButton;
removeAllScenesButton = new QPushButton;

addSceneButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSceneButton->setStyleSheet("background-color: transparent;");
addSceneButton->setIcon(QIcon(QPixmap(":icons/scene.png")));
addSceneButton->setIconSize(QSize(38, 38));
addSceneButton->setToolTip("Add Mp3 Track");
addSceneButton->setToolTipDuration(1000);

stopAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllScenesButton->setStyleSheet("background-color: transparent;");
stopAllScenesButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllScenesButton->setIconSize(QSize(38, 38));
stopAllScenesButton->setToolTip("Stop All Tracks");
stopAllScenesButton->setToolTipDuration(1000);

removeAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllScenesButton->setStyleSheet("background-color: transparent;");
removeAllScenesButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllScenesButton->setIconSize(QSize(38, 38));
removeAllScenesButton->setToolTip("Remove All Tracks");
removeAllScenesButton->setToolTipDuration(1000);

sceneGrid = new QGridLayout;
scenePanel = new QWidget;
scenePanelLayout = new QHBoxLayout;
hSceneLayout = new QHBoxLayout;
vSceneLayout = new QVBoxLayout;
sceneScroll->setLayout(vSceneLayout);

scenePanelLayout->addWidget(addSceneButton);
scenePanelLayout->addWidget(stopAllScenesButton);
scenePanelLayout->addWidget(removeAllScenesButton);

scenePanelLayout->addStretch(1);

scenePanel->setLayout(scenePanelLayout);

hSceneLayout->addLayout(sceneGrid);
hSceneLayout->addStretch(1);

vSceneLayout->addWidget(scenePanel);
vSceneLayout->addLayout(hSceneLayout);
vSceneLayout->addStretch(1);


void CustomTabWidget::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void CustomTabWidget::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dropEvent(QDropEvent *event)
QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(soundCol < 3)
appendSound(fileList, i);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(fileList, i);
++soundCol;


else
return;



void CustomTabWidget::removeSound(Player *player)
players.removeAll(player);
player->~Player();

soundGrid->~QGridLayout();
soundGrid = new QGridLayout;
hSoundLayout->insertLayout(hSoundLayout->count() - 1, soundGrid);

soundRow = 0;
soundCol = 0;
int counter = 0;
while(counter < players.size())
if(soundCol < 3)
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;
else
soundCol = 0;
++soundRow;
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;

++counter;



void CustomTabWidget::removeAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
soundCol = 0;
soundRow = 0;


void CustomTabWidget::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void CustomTabWidget::addScene(bool checked)
(void)checked;

bool ok;
QString title = QInputDialog::getText(this, "Scene Title",
"Title: ", QLineEdit::Normal,
"", &ok);
if (ok && !title.isEmpty())
if(sceneCol < 5)
appendScene(title);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
appendScene(title);
++sceneCol;

else
return;



void CustomTabWidget::stopAllScenes(bool checked)
(void)checked;
for(int i = 0; i < scenes.size(); ++i)
if(scenes.at(i)->getPlayStopButton()->isChecked())
scenes.at(i)->playStop(false);
scenes.at(i)->getPlayStopButton()->setChecked(false);
// scenes.at(i)->getPlayStopButton()->click();




void CustomTabWidget::removeScene(Scene *scene)
scenes.removeAll(scene);
scene->~Scene();

sceneGrid->~QGridLayout();
sceneGrid = new QGridLayout;
hSceneLayout->insertLayout(hSceneLayout->count() - 1, sceneGrid);

sceneRow = 0;
sceneCol = 0;
int counter = 0;
while(counter < scenes.size())
if(sceneCol < 5)
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;

++counter;



void CustomTabWidget::removeAllScenes(bool checked)
(void)checked;

for(int i = 0; i < scenes.size(); ++i)
scenes.at(i)->~Scene();

scenes.clear();
sceneCol = 0;
sceneRow = 0;


void CustomTabWidget::appendSound(QStringList &list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &CustomTabWidget::removeSound);
qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
qDebug() << file << endl;
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
soundGrid->addWidget(players.at(players.size() - 1), soundRow, soundCol);


void CustomTabWidget::appendScene(QString title)
Scene *scene = new Scene;
connect(scene, &Scene::thisScene, this, &CustomTabWidget::removeScene);
scenes.append(scene);
scene->setTitle(title);
sceneGrid->addWidget(scene, sceneRow, sceneCol);



main.cpp



#include "widget.h"
#include <QApplication>

int main(int argc, char *argv)
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();



player.cpp



#include "player.h"
#include "ui_player.h"

#include <QPainter>

Player::Player(QWidget *parent) : QWidget(parent),
ui(new Ui::Player)
ui->setupUi(this);

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setValue(50);
ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);

ui->deleteButton->setToolTip("Delete");
ui->deleteButton->setToolTipDuration(500);


mPlayer = new QMediaPlayer(this);
mPlaylist = new QMediaPlaylist(this);
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
mPlayer->setPlaylist(mPlaylist);
mPlayer->setVolume(ui->volumeSlider->value());

connect(ui->playStopButton, &QPushButton::clicked, this, &Player::playStopButton);
connect(ui->deleteButton, &QPushButton::clicked, this, &Player::emitThisPlayer);
connect(mPlayer, &QMediaPlayer::stateChanged, this, &Player::soundEnd);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Player::loop);
connect(ui->volumeSlider, &QSlider::valueChanged, mPlayer, &QMediaPlayer::setVolume);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Player::sliderValueChanged);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
setIconState("play");
ui->playStopButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Player::~Player()
delete ui;


void Player::loop(bool checked)
if(checked)
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
else
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);



void Player::soundEnd(QMediaPlayer::State state)
if(state == QMediaPlayer::State::StoppedState)
setIconState("play");
ui->playStopButton->setChecked(false);



void Player::playStopButton(bool checked)
if(checked)
setIconState("stop");
mPlayer->play();
else
setIconState("play");
if(mPlayer->state() == QMediaPlayer::State::PlayingState)
mPlayer->stop();
else
return;




void Player::setTitle(QString title)
ui->titleLabel->setText(title);


void Player::setIconState(QString str)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/" + str + ".png")));


float Player::getSliderValue()
return (float)ui->volumeSlider->value();


QPushButton* Player::getPlayStopButton()
return ui->playStopButton;


QCheckBox* Player::getLoopButton()
return ui->loopCheckBox;


QMediaPlayer *Player::getPlayer()
return mPlayer;


QMediaPlaylist *Player::getPlaylist()
return mPlaylist;


void Player::emitThisPlayer(bool checked)
(void)checked;
emit thisPlayer(this);



scene.cpp



#include "scene.h"
#include "ui_scene.h"

#include <QFileDialog>
#include <QCloseEvent>

#include <QStringList>
#include <QMimeData>

Scene::Scene(QWidget *parent) : QWidget(parent),
ui(new Ui::Scene)
ui->setupUi(this);

stoppedCounter = 0;

setEditorLayout();

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);
ui->volumeSlider->setValue(50);

ui->deleteButton->setToolTip("Delete Scene");
ui->deleteButton->setToolTipDuration(500);

connect(ui->playStopButton, &QPushButton::clicked, this, &Scene::playStop);
connect(ui->editorButton, &QPushButton::clicked, this, &Scene::showEditor);
connect(ui->deleteButton, &QPushButton::clicked, this, &Scene::emitThisScene);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Scene::loopScene);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Scene::masterVolume);

connect(add, &QPushButton::clicked, this, &Scene::addSound);
connect(stopAll, &QPushButton::clicked, this, &Scene::stopAllSounds);
connect(removeAll, &QPushButton::clicked, this, &Scene::removeAllSounds);
connect(editorPS, &QPushButton::clicked, this, &Scene::playStop);
// connect(editor, &Editor::hidden, this, &Scene::playStop);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setIconSize(QSize(28, 28));

ui->editorButton->setStyleSheet("background-color: transparent;");
ui->editorButton->setIcon(QIcon(QPixmap(":/icons/settings.png")));
ui->editorButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Scene::~Scene()
delete ui;


void Editor::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void Editor::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void Editor::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void Editor::dropEvent(QDropEvent *event)

QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



void Editor::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



int Scene::getCol()
return col;


void Scene::setCol(int i)
col = i;


int Scene::getRow()
return row;


void Scene::setRow(int i)
row = i;


Editor::Editor(Scene *parent) : QWidget(parent)
scene = parent;


void Editor::resizeEvent(QResizeEvent *evt)
QPixmap bkgnd(":/images/library wizard.jpg");
bkgnd = bkgnd.scaled(size(), Qt::IgnoreAspectRatio);
QPalette p = palette(); //copy current, not create new
p.setBrush(QPalette::Background, bkgnd);
setPalette(p);

QWidget::resizeEvent(evt); //call base implementation


void Editor::closeEvent(QCloseEvent *event)
event->ignore();
scene->stopAllSounds(true);
this->hide();

// emit hidden(false);


Editor::~Editor()



void Scene::masterVolume(int i)
for(int j = 0; j < players.size(); ++j)
players.at(j)->getPlayer()->setVolume((players.at(j)->getSliderValue() / 100) * i);



void Scene::setMasterVolume(int i)
(void)i;
masterVolume(ui->volumeSlider->value());


void Scene::soundEnd()
qDebug() << endl << "soundEnd() Emitido";
if(stoppedCounter == 0)
qDebug() << "Scene play/stop Button checked false" << endl;
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(false);

editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(false);



void Scene::playerStateChanged(QMediaPlayer::State state)
qDebug() << endl << "Player stateChanged() Emited!";
if(state == QMediaPlayer::State::PlayingState)
++stoppedCounter;
qDebug() << "Counter ++: " << stoppedCounter << endl;
else
--stoppedCounter;
qDebug() << "Counter --: " << stoppedCounter << endl;

soundEnd();


void Scene::loopScene(bool checked)
for(int i = 0; i < players.size(); ++i)
players.at(i)->getLoopButton()->setChecked(checked);
players.at(i)->loop(checked);



void Scene::playStop(bool checked)
if(checked)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/stop.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/stop.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(false);
players.at(i)->getPlayStopButton()->setChecked(false);



/* Los toca todos */
for(int i = 0; i < players.size(); ++i)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);

else
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);





void Scene::removeAllSounds(bool checked)
(void)checked;

for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
col = 0;
row = 0;
stoppedCounter = 0;


void Scene::removeSound(Player *player)
players.removeAll(player);

if(player->getPlayer()->PlayingState == QMediaPlayer::PlayingState)
--stoppedCounter;


player->~Player();

grid->~QGridLayout();
grid = new QGridLayout;
h->insertLayout(h->count() - 1, grid);

row = 0;
col = 0;
int counter = 0;
while(counter < players.size())
if(col < 3)
grid->addWidget(players.at(counter), row, col);
++col;
else
col = 0;
++row;
grid->addWidget(players.at(counter), row, col);
++col;

++counter;

soundEnd();


void Scene::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(col < 3)
appendSound(fileList, i);
++col;
else
col = 0;
row++;
appendSound(fileList, i);
++col;


else
return;



void Scene::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void Scene::setEditorLayout()
col = 0;
row = 0;

CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



editor = new Editor(this);
// editor->setScene(this);
editor->setWindowFlags(Qt::Window);
editor->setWindowModality(Qt::WindowModal);
editor->setAcceptDrops(true);

connect(listWidget, &CustomListWidget::customItem, editor, &Editor::addDefaultSound);

panel = new QWidget;

add = new QPushButton;
stopAll = new QPushButton;
removeAll = new QPushButton;
editorPS = new QPushButton;
editorPS->setCheckable(true);

add->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
add->setStyleSheet("background-color: transparent;");
add->setIcon(QIcon(QPixmap(":icons/add.png")));
add->setIconSize(QSize(38, 38));
add->setToolTip("Add Mp3 Sound");
add->setToolTipDuration(500);

stopAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAll->setStyleSheet("background-color: transparent;");
stopAll->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAll->setIconSize(QSize(38, 38));
stopAll->setToolTip("Stop All Sounds");
stopAll->setToolTipDuration(500);

removeAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAll->setStyleSheet("background-color: transparent;");
removeAll->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAll->setIconSize(QSize(38, 38));
removeAll->setToolTip("Remove All Sounds");
removeAll->setToolTipDuration(500);

editorPS->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
editorPS->setStyleSheet("background-color: transparent;");
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setIconSize(QSize(28, 28));
editorPS->setToolTip("Play / Stop All Sounds");
editorPS->setToolTipDuration(500);

grid = new QGridLayout;
panelLayout = new QHBoxLayout;
h = new QHBoxLayout;
v = new QVBoxLayout;

panelLayout->addWidget(add);
panelLayout->addWidget(stopAll);
panelLayout->addWidget(removeAll);
panelLayout->addWidget(editorPS);
panelLayout->addStretch(1);

panel->setLayout(panelLayout);

h->addLayout(grid);
h->addStretch(1);

v->addWidget(panel);
v->addLayout(h);
v->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(v);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

editor->setLayout(finalLayout);


void Scene::showEditor(bool checked)
(void)checked;

editor->setWindowTitle("Ambience Editor: " + ui->titleLabel->text());
editor->resize(400, 300);
editor->show();


void Scene::emitThisScene(bool checked)
(void)checked;
emit thisScene(this);


void Scene::setTitle(QString title)
ui->titleLabel->setText(title);


QPushButton* Scene::getPlayStopButton()
return ui->playStopButton;


void Scene::appendSound(QStringList list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &Scene::removeSound);
connect(players.at(players.size() - 1), &Player::sliderValueChanged, this, &Scene::setMasterVolume);

/* La conexion garantiza que si no hay ningun sonido en loop dentro del editor, el boton
* de play de la Scene cambie de estado */

connect(players.at(players.size() - 1)->getPlayer(), &QMediaPlayer::stateChanged,
this, &Scene::playerStateChanged);

qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
grid->addWidget(players.at(players.size() - 1), row, col);



widget.cpp



#include "widget.h"
#include "ui_widget.h"

#include "customtabwidget.h"

#include <QHBoxLayout>

#include <QDir>
#include <QFileInfoList>

Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);

QHBoxLayout *layout = new QHBoxLayout(this);

CustomTabWidget *tabWidget = new CustomTabWidget;

layout->addWidget(tabWidget);

this->setWindowTitle("TableTop SoundBoard v2.0");
this->resize(800, 600);


Widget::~Widget()
delete ui;







share|improve this question













I've been working on a soundboard software for tabletop games audio immersion in C++ using Qt. The software consists of 2 tabs who provides to a game master a set of individual sounds or scenes to be payed for a particular moment in the game.



The game master can choose the audio to play and the audio is embedded in a resource file from Qt. Besides taking almost 1.5 GB in ram (which have to be wrong), in general the software is running fine, the thing is for the past 2 weeks I feel like I'm not using C++ and Qt the way they are meant to. I'm just pretending to.



I try to come up with C++ 11, 14 and 17 as well as the "Qt way" standards to code (why I'm forced to create so many pointers: the compiler complains when I don't create one...) but it's just not as straightforward as I would like it to be. I want my code to be more elegant, more expressive, more verbose and efficient when running.



If anyone can take the time and point out where my weak spots are in general and what should be my thought process when writing code that would be of great help. If this is not the right place to ask for a code review of like this I'm sure you will point me out on the right direction.



.pro



QT += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SoundBoard
TEMPLATE = app

CONFIG += resources_big

RC_ICONS = Codex_book.ico

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES +=
main.cpp
widget.cpp
customlistwidget.cpp
customlistwidgetitem.cpp
customtabwidget.cpp
player.cpp
scene.cpp

HEADERS +=
widget.h
customlistwidget.h
customlistwidgetitem.h
customtabwidget.h
player.h
scene.h

FORMS +=
widget.ui
player.ui
scene.ui
player.ui

RESOURCES +=
src.qrc


Headers:



customlistwidget.h



#ifndef CUSTOMLISTWIDGET_H
#define CUSTOMLISTWIDGET_H

#include <QListWidget>
#include <QVector>

#include "customlistwidgetitem.h"

class CustomListWidget : public QListWidget
Q_OBJECT
public:
CustomListWidget(QWidget *parent = nullptr);

void addCustomItem(CustomListWidgetItem*);

public slots:
void setItemPressed(QListWidgetItem*);
void emitCustomItem(QListWidgetItem*);

signals:
void customItem(CustomListWidgetItem*);

protected:
void startDrag(Qt::DropActions supportedActions);

private:
QVector<CustomListWidgetItem*> list;
QListWidgetItem *itemToBeSet;
;

#endif // CUSTOMLISTWIDGET_H


customlistwidgetitem.h



#ifndef CUSTOMLISTWIDGETITEM_H
#define CUSTOMLISTWIDGETITEM_H

#include <QListWidgetItem>
#include <QFileInfo>

class CustomListWidgetItem : public QListWidgetItem
public:
CustomListWidgetItem(QFileInfo, QIcon, QListWidget *parent = nullptr);
~CustomListWidgetItem();

QFileInfo getFileInfo();

private:
QFileInfo fileInfo;
;

#endif // CUSTOMLISTWIDGETITEM_H


customtabwidget.h



#ifndef CUSTOMTABWIDGET_H
#define CUSTOMTABWIDGET_H

#include <QTabWidget>
#include <QWidget>

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>

#include <QScrollArea>

#include <QPushButton>

#include <QVector>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "scene.h"
#include "player.h"
#include "customlistwidgetitem.h"

class CustomTabWidget : public QTabWidget
Q_OBJECT

public:
CustomTabWidget(QWidget *parent = nullptr);

void setSoundLayout();
void setSceneLayout();

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

public slots:
void addScene(bool);
void stopAllScenes(bool);
void removeScene(Scene*);
void removeAllScenes(bool);


void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player*);
void removeAllSounds(bool);

void addDefaultSound(CustomListWidgetItem*);

private:
void appendSound(QStringList &, int);
void appendScene(QString);

QVector<Scene*> scenes;
QVector<Player*> players;

QGridLayout *soundGrid;
QGridLayout *sceneGrid;

QWidget *soundPanel;
QWidget *scenePanel;

QHBoxLayout *soundPanelLayout;
QHBoxLayout *scenePanelLayout;

QHBoxLayout *hSoundLayout;
QVBoxLayout *vSoundLayout;

QHBoxLayout *hSceneLayout;
QVBoxLayout *vSceneLayout;

int soundCol;
int soundRow;

int sceneCol;
int sceneRow;

QPushButton *addSoundButton;
QPushButton *removeAllSoundsButton;
QPushButton *stopAllSoundsButton;

QPushButton *addSceneButton;
QPushButton *removeAllScenesButton;
QPushButton *stopAllScenesButton;

QScrollArea *scrollSound;
QScrollArea *scrollScene;

QWidget *soundScroll;
QWidget *sceneScroll;
;

#endif // CUSTOMTABWIDGET_H


player.h



#ifndef PLAYER_H
#define PLAYER_H

#include <QWidget>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QCheckBox>
#include <QPushButton>

namespace Ui
class Player;


class Player : public QWidget
Q_OBJECT

public:
explicit Player(QWidget *parent = 0);
~Player();

void setTitle(QString);
void setIconState(QString);

QMediaPlaylist *getPlaylist();
QMediaPlayer *getPlayer();
QCheckBox* getLoopButton();
QPushButton* getPlayStopButton();
float getSliderValue();

public slots:
void playStopButton(bool);
void soundEnd(QMediaPlayer::State);
void loop(bool);
void emitThisPlayer(bool);

signals:
void thisPlayer(Player*);
void stateChanged(QMediaPlayer::State);
void sliderValueChanged(int);

private:
Ui::Player *ui;

QMediaPlayer *mPlayer;
QMediaPlaylist *mPlaylist;

float volume;
;

#endif // PLAYER_H


scene.h



#ifndef SCENE_H
#define SCENE_H

#include <QWidget>
#include <QPushButton>
#include <QGridLayout>

#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QMoveEvent>
#include <QDropEvent>

#include "player.h"
#include "customlistwidget.h"

namespace Ui
class Scene;


class Scene;

class Editor : public QWidget
Q_OBJECT

public:
explicit Editor(Scene *parent = 0);
~Editor();

void addDefaultSound(CustomListWidgetItem*);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent*);

void resizeEvent(QResizeEvent *evt);
void closeEvent(QCloseEvent *event);

signals:
void hidden(bool);

private:
Scene *scene;
;

class Scene : public QWidget
Q_OBJECT

public:
explicit Scene(QWidget *parent = 0);
~Scene();

void appendSound(QStringList, int);

int getCol();
void setCol(int);

int getRow();
void setRow(int);

void setTitle(QString);
QPushButton *getPlayStopButton();

public slots:
void emitThisScene(bool);
void showEditor(bool);
void playStop(bool);
void loopScene(bool);
void playerStateChanged(QMediaPlayer::State);
void soundEnd();
void masterVolume(int);
void setMasterVolume(int);

void addSound(bool);
void stopAllSounds(bool);
void removeSound(Player *player);
void removeAllSounds(bool);

signals:
void thisScene(Scene*);

private:
void setEditorLayout();

Ui::Scene *ui;
QVector<Player*> players;

Editor *editor;

QPushButton *add;
QPushButton *stopAll;
QPushButton *removeAll;
QPushButton *editorPS;

QGridLayout *grid;
QWidget *panel;

QHBoxLayout *h;
QVBoxLayout *v;

QHBoxLayout *panelLayout;

int col;
int row;

int stoppedCounter;
;

#endif // SCENE_H


widget.h



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui
class Widget;


class Widget : public QWidget
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
;

#endif // WIDGET_H


Sources:



customlistwidget.cpp



#include "customlistwidget.h"

#include <QMouseEvent>

#include <QMimeData>
#include <QDrag>

#include <QList>
#include <QUrl>

#include <QByteArray>

#include <QDebug>

CustomListWidget::CustomListWidget(QWidget *parent) : QListWidget(parent)

setMouseTracking(true);

setDragEnabled(true);
setDragDropMode(QListWidget::DragOnly);

connect(this, &CustomListWidget::itemEntered, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemClicked, this, &CustomListWidget::setItemPressed);
connect(this, &CustomListWidget::itemDoubleClicked, this, &CustomListWidget::emitCustomItem);
itemToBeSet = nullptr;

setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);


void CustomListWidget::addCustomItem(CustomListWidgetItem *customItem)
list.push_back(customItem);
qDebug() << "Custom Item Added: " << list.size() << endl;
QListWidgetItem *item = new QListWidgetItem(this);
item->setText(customItem->text());
item->setIcon(customItem->icon());


void CustomListWidget::setItemPressed(QListWidgetItem *item)
itemToBeSet = item;
qDebug() << "set" << endl;


void CustomListWidget::emitCustomItem(QListWidgetItem *item)
for(int i = 0; i < list.size(); ++i)
if(item->text() == list.at(i)->getFileInfo().baseName())
emit customItem(list.at(i));




void CustomListWidget::startDrag(Qt::DropActions supportedActions)
(void)supportedActions;
QList<QUrl> url;

QByteArray ba;

QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;

if(itemToBeSet)
for(int i = 0; i < list.size(); ++i)
if(itemToBeSet->text() == list.at(i)->text())
ba.append(list.at(i)->getFileInfo().absoluteFilePath());




mimeData->setData("FileInfo", ba);

drag->setMimeData(mimeData);
drag->exec();



customlistwidgetitem.cpp



#include "customlistwidgetitem.h"

#include <QDebug>

CustomListWidgetItem::CustomListWidgetItem(QFileInfo infoFile, QIcon icon, QListWidget *parent)
: QListWidgetItem(parent)

fileInfo = infoFile;

setText(infoFile.baseName());
setIcon(icon);


CustomListWidgetItem::~CustomListWidgetItem()
delete &fileInfo;


QFileInfo CustomListWidgetItem::getFileInfo()
return fileInfo;



customtabwidget.cpp



#include "customtabwidget.h"

#include "customlistwidget.h"

#include <QMimeData>

#include <QFileDialog>
#include <QInputDialog>

CustomTabWidget::CustomTabWidget(QWidget *parent) : QTabWidget(parent)

scrollSound = new QScrollArea(this);
soundScroll = new QWidget(scrollSound);
soundScroll->setStyleSheet("background-image: url(:/images/Listen.png");

scrollSound->setWidgetResizable(true);
soundScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSoundLayout();

scrollScene = new QScrollArea(this);
sceneScroll = new QWidget(scrollScene);
scrollScene->setWidgetResizable(true);
sceneScroll->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setSceneLayout();

scrollSound->setWidget(soundScroll);
scrollScene->setWidget(sceneScroll);

addTab(scrollSound, "Sounds");
addTab(scrollScene, "Ambience");

setAcceptDrops(true);

connect(addSoundButton, &QPushButton::clicked, this, &CustomTabWidget::addSound);
connect(stopAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllSounds);
connect(removeAllSoundsButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllSounds);

connect(addSceneButton, &QPushButton::clicked, this, &CustomTabWidget::addScene);
connect(stopAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::stopAllScenes);
connect(removeAllScenesButton, &QPushButton::clicked, this, &CustomTabWidget::removeAllScenes);


void CustomTabWidget::setSoundLayout()
CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



connect(listWidget, &CustomListWidget::customItem, this, &CustomTabWidget::addDefaultSound);

soundCol = 0;
soundRow = 0;

addSoundButton = new QPushButton;
stopAllSoundsButton = new QPushButton;
removeAllSoundsButton = new QPushButton;

addSoundButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSoundButton->setStyleSheet("background-color: transparent;");
addSoundButton->setIcon(QIcon(QPixmap(":icons/add.png")));
addSoundButton->setIconSize(QSize(38, 38));
addSoundButton->setToolTip("Add Mp3 Track");
addSoundButton->setToolTipDuration(1000);

stopAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllSoundsButton->setStyleSheet("background-color: transparent;");
stopAllSoundsButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllSoundsButton->setIconSize(QSize(38, 38));
stopAllSoundsButton->setToolTip("Stop All Tracks");
stopAllSoundsButton->setToolTipDuration(1000);

removeAllSoundsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllSoundsButton->setStyleSheet("background-color: transparent;");
removeAllSoundsButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllSoundsButton->setIconSize(QSize(38, 38));
removeAllSoundsButton->setToolTip("Remove All Tracks");
removeAllSoundsButton->setToolTipDuration(1000);

soundPanel = new QWidget;
soundPanelLayout = new QHBoxLayout;

soundGrid = new QGridLayout;

hSoundLayout = new QHBoxLayout;
vSoundLayout = new QVBoxLayout;

soundPanelLayout->addWidget(addSoundButton);
soundPanelLayout->addWidget(stopAllSoundsButton);
soundPanelLayout->addWidget(removeAllSoundsButton);
soundPanelLayout->addStretch(1);

soundPanel->setLayout(soundPanelLayout);

hSoundLayout->addLayout(soundGrid);
hSoundLayout->addStretch(1);

vSoundLayout->addWidget(soundPanel);
vSoundLayout->addLayout(hSoundLayout);
vSoundLayout->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(vSoundLayout);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

soundScroll->setLayout(finalLayout);


void CustomTabWidget::setSceneLayout()
sceneCol = 0;
sceneRow = 0;

addSceneButton = new QPushButton;
stopAllScenesButton = new QPushButton;
removeAllScenesButton = new QPushButton;

addSceneButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
addSceneButton->setStyleSheet("background-color: transparent;");
addSceneButton->setIcon(QIcon(QPixmap(":icons/scene.png")));
addSceneButton->setIconSize(QSize(38, 38));
addSceneButton->setToolTip("Add Mp3 Track");
addSceneButton->setToolTipDuration(1000);

stopAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAllScenesButton->setStyleSheet("background-color: transparent;");
stopAllScenesButton->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAllScenesButton->setIconSize(QSize(38, 38));
stopAllScenesButton->setToolTip("Stop All Tracks");
stopAllScenesButton->setToolTipDuration(1000);

removeAllScenesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAllScenesButton->setStyleSheet("background-color: transparent;");
removeAllScenesButton->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAllScenesButton->setIconSize(QSize(38, 38));
removeAllScenesButton->setToolTip("Remove All Tracks");
removeAllScenesButton->setToolTipDuration(1000);

sceneGrid = new QGridLayout;
scenePanel = new QWidget;
scenePanelLayout = new QHBoxLayout;
hSceneLayout = new QHBoxLayout;
vSceneLayout = new QVBoxLayout;
sceneScroll->setLayout(vSceneLayout);

scenePanelLayout->addWidget(addSceneButton);
scenePanelLayout->addWidget(stopAllScenesButton);
scenePanelLayout->addWidget(removeAllScenesButton);

scenePanelLayout->addStretch(1);

scenePanel->setLayout(scenePanelLayout);

hSceneLayout->addLayout(sceneGrid);
hSceneLayout->addStretch(1);

vSceneLayout->addWidget(scenePanel);
vSceneLayout->addLayout(hSceneLayout);
vSceneLayout->addStretch(1);


void CustomTabWidget::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void CustomTabWidget::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void CustomTabWidget::dropEvent(QDropEvent *event)
QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(soundCol < 3)
appendSound(fileList, i);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(fileList, i);
++soundCol;


else
return;



void CustomTabWidget::removeSound(Player *player)
players.removeAll(player);
player->~Player();

soundGrid->~QGridLayout();
soundGrid = new QGridLayout;
hSoundLayout->insertLayout(hSoundLayout->count() - 1, soundGrid);

soundRow = 0;
soundCol = 0;
int counter = 0;
while(counter < players.size())
if(soundCol < 3)
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;
else
soundCol = 0;
++soundRow;
soundGrid->addWidget(players.at(counter), soundRow, soundCol);
++soundCol;

++counter;



void CustomTabWidget::removeAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
soundCol = 0;
soundRow = 0;


void CustomTabWidget::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(soundCol < 3)
appendSound(list, 0);
++soundCol;
else
soundCol = 0;
soundRow++;
appendSound(list, 0);
++soundCol;



void CustomTabWidget::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void CustomTabWidget::addScene(bool checked)
(void)checked;

bool ok;
QString title = QInputDialog::getText(this, "Scene Title",
"Title: ", QLineEdit::Normal,
"", &ok);
if (ok && !title.isEmpty())
if(sceneCol < 5)
appendScene(title);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
appendScene(title);
++sceneCol;

else
return;



void CustomTabWidget::stopAllScenes(bool checked)
(void)checked;
for(int i = 0; i < scenes.size(); ++i)
if(scenes.at(i)->getPlayStopButton()->isChecked())
scenes.at(i)->playStop(false);
scenes.at(i)->getPlayStopButton()->setChecked(false);
// scenes.at(i)->getPlayStopButton()->click();




void CustomTabWidget::removeScene(Scene *scene)
scenes.removeAll(scene);
scene->~Scene();

sceneGrid->~QGridLayout();
sceneGrid = new QGridLayout;
hSceneLayout->insertLayout(hSceneLayout->count() - 1, sceneGrid);

sceneRow = 0;
sceneCol = 0;
int counter = 0;
while(counter < scenes.size())
if(sceneCol < 5)
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;
else
sceneCol = 0;
++sceneRow;
sceneGrid->addWidget(scenes.at(counter), sceneRow, sceneCol);
++sceneCol;

++counter;



void CustomTabWidget::removeAllScenes(bool checked)
(void)checked;

for(int i = 0; i < scenes.size(); ++i)
scenes.at(i)->~Scene();

scenes.clear();
sceneCol = 0;
sceneRow = 0;


void CustomTabWidget::appendSound(QStringList &list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &CustomTabWidget::removeSound);
qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
qDebug() << file << endl;
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
soundGrid->addWidget(players.at(players.size() - 1), soundRow, soundCol);


void CustomTabWidget::appendScene(QString title)
Scene *scene = new Scene;
connect(scene, &Scene::thisScene, this, &CustomTabWidget::removeScene);
scenes.append(scene);
scene->setTitle(title);
sceneGrid->addWidget(scene, sceneRow, sceneCol);



main.cpp



#include "widget.h"
#include <QApplication>

int main(int argc, char *argv)
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();



player.cpp



#include "player.h"
#include "ui_player.h"

#include <QPainter>

Player::Player(QWidget *parent) : QWidget(parent),
ui(new Ui::Player)
ui->setupUi(this);

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setValue(50);
ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);

ui->deleteButton->setToolTip("Delete");
ui->deleteButton->setToolTipDuration(500);


mPlayer = new QMediaPlayer(this);
mPlaylist = new QMediaPlaylist(this);
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
mPlayer->setPlaylist(mPlaylist);
mPlayer->setVolume(ui->volumeSlider->value());

connect(ui->playStopButton, &QPushButton::clicked, this, &Player::playStopButton);
connect(ui->deleteButton, &QPushButton::clicked, this, &Player::emitThisPlayer);
connect(mPlayer, &QMediaPlayer::stateChanged, this, &Player::soundEnd);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Player::loop);
connect(ui->volumeSlider, &QSlider::valueChanged, mPlayer, &QMediaPlayer::setVolume);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Player::sliderValueChanged);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
setIconState("play");
ui->playStopButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Player::~Player()
delete ui;


void Player::loop(bool checked)
if(checked)
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
else
mPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);



void Player::soundEnd(QMediaPlayer::State state)
if(state == QMediaPlayer::State::StoppedState)
setIconState("play");
ui->playStopButton->setChecked(false);



void Player::playStopButton(bool checked)
if(checked)
setIconState("stop");
mPlayer->play();
else
setIconState("play");
if(mPlayer->state() == QMediaPlayer::State::PlayingState)
mPlayer->stop();
else
return;




void Player::setTitle(QString title)
ui->titleLabel->setText(title);


void Player::setIconState(QString str)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/" + str + ".png")));


float Player::getSliderValue()
return (float)ui->volumeSlider->value();


QPushButton* Player::getPlayStopButton()
return ui->playStopButton;


QCheckBox* Player::getLoopButton()
return ui->loopCheckBox;


QMediaPlayer *Player::getPlayer()
return mPlayer;


QMediaPlaylist *Player::getPlaylist()
return mPlaylist;


void Player::emitThisPlayer(bool checked)
(void)checked;
emit thisPlayer(this);



scene.cpp



#include "scene.h"
#include "ui_scene.h"

#include <QFileDialog>
#include <QCloseEvent>

#include <QStringList>
#include <QMimeData>

Scene::Scene(QWidget *parent) : QWidget(parent),
ui(new Ui::Scene)
ui->setupUi(this);

stoppedCounter = 0;

setEditorLayout();

ui->playStopButton->setCheckable(true);
ui->playStopButton->setToolTip("Play / Stop");
ui->playStopButton->setToolTipDuration(500);

ui->volumeSlider->setToolTip("volume");
ui->volumeSlider->setToolTipDuration(500);
ui->volumeSlider->setValue(50);

ui->deleteButton->setToolTip("Delete Scene");
ui->deleteButton->setToolTipDuration(500);

connect(ui->playStopButton, &QPushButton::clicked, this, &Scene::playStop);
connect(ui->editorButton, &QPushButton::clicked, this, &Scene::showEditor);
connect(ui->deleteButton, &QPushButton::clicked, this, &Scene::emitThisScene);
connect(ui->loopCheckBox, &QCheckBox::clicked, this, &Scene::loopScene);
connect(ui->volumeSlider, &QSlider::valueChanged, this, &Scene::masterVolume);

connect(add, &QPushButton::clicked, this, &Scene::addSound);
connect(stopAll, &QPushButton::clicked, this, &Scene::stopAllSounds);
connect(removeAll, &QPushButton::clicked, this, &Scene::removeAllSounds);
connect(editorPS, &QPushButton::clicked, this, &Scene::playStop);
// connect(editor, &Editor::hidden, this, &Scene::playStop);

QFont font;
font.setBold(true);
font.setFamily("Arial");
font.setPointSize(10);
ui->titleLabel->setFont(font);

// QColor color = QColor(Qt::white);
// QPalette palette = ui->titleLabel->palette();
// palette.setColor(QPalette::WindowText, color);
// ui->titleLabel->setPalette(palette);

ui->playStopButton->setStyleSheet("background-color: transparent;");
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setIconSize(QSize(28, 28));

ui->editorButton->setStyleSheet("background-color: transparent;");
ui->editorButton->setIcon(QIcon(QPixmap(":/icons/settings.png")));
ui->editorButton->setIconSize(QSize(28, 28));

ui->deleteButton->setStyleSheet("background-color: transparent;");
ui->deleteButton->setIcon(QIcon(QPixmap(":/icons/minus.png")));
ui->deleteButton->setIconSize(QSize(28, 28));

setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);


Scene::~Scene()
delete ui;


void Editor::dragEnterEvent(QDragEnterEvent *event)
event->acceptProposedAction();


void Editor::dragLeaveEvent(QDragLeaveEvent *event)
event->accept();


void Editor::dragMoveEvent(QDragMoveEvent *event)
event->acceptProposedAction();


void Editor::dropEvent(QDropEvent *event)

QStringList list;
list.append("qrc" + event->mimeData()->data("FileInfo"));

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



void Editor::addDefaultSound(CustomListWidgetItem *item)

QString path = "qrc" + item->getFileInfo().absoluteFilePath();

QStringList list;
list.append(path);

qDebug() << list << endl;

if(scene->getCol() < 3)
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);
else
scene->setCol(0);
scene->setRow(scene->getRow() + 1);
scene->appendSound(list, 0);
scene->setCol(scene->getCol() + 1);



int Scene::getCol()
return col;


void Scene::setCol(int i)
col = i;


int Scene::getRow()
return row;


void Scene::setRow(int i)
row = i;


Editor::Editor(Scene *parent) : QWidget(parent)
scene = parent;


void Editor::resizeEvent(QResizeEvent *evt)
QPixmap bkgnd(":/images/library wizard.jpg");
bkgnd = bkgnd.scaled(size(), Qt::IgnoreAspectRatio);
QPalette p = palette(); //copy current, not create new
p.setBrush(QPalette::Background, bkgnd);
setPalette(p);

QWidget::resizeEvent(evt); //call base implementation


void Editor::closeEvent(QCloseEvent *event)
event->ignore();
scene->stopAllSounds(true);
this->hide();

// emit hidden(false);


Editor::~Editor()



void Scene::masterVolume(int i)
for(int j = 0; j < players.size(); ++j)
players.at(j)->getPlayer()->setVolume((players.at(j)->getSliderValue() / 100) * i);



void Scene::setMasterVolume(int i)
(void)i;
masterVolume(ui->volumeSlider->value());


void Scene::soundEnd()
qDebug() << endl << "soundEnd() Emitido";
if(stoppedCounter == 0)
qDebug() << "Scene play/stop Button checked false" << endl;
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(false);

editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(false);



void Scene::playerStateChanged(QMediaPlayer::State state)
qDebug() << endl << "Player stateChanged() Emited!";
if(state == QMediaPlayer::State::PlayingState)
++stoppedCounter;
qDebug() << "Counter ++: " << stoppedCounter << endl;
else
--stoppedCounter;
qDebug() << "Counter --: " << stoppedCounter << endl;

soundEnd();


void Scene::loopScene(bool checked)
for(int i = 0; i < players.size(); ++i)
players.at(i)->getLoopButton()->setChecked(checked);
players.at(i)->loop(checked);



void Scene::playStop(bool checked)
if(checked)
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/stop.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/stop.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(false);
players.at(i)->getPlayStopButton()->setChecked(false);



/* Los toca todos */
for(int i = 0; i < players.size(); ++i)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);

else
ui->playStopButton->setIcon(QIcon(QPixmap(":/icons/play.png")));
ui->playStopButton->setChecked(checked);
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setChecked(checked);

/* Si hay alguien tocando lo para */
for(int i = 0; i < players.size(); ++i)
if(players.at(i)->getPlayer()->state() == QMediaPlayer::PlayingState)
players.at(i)->playStopButton(checked);
players.at(i)->getPlayStopButton()->setChecked(checked);





void Scene::removeAllSounds(bool checked)
(void)checked;

for(int i = 0; i < players.size(); ++i)
players.at(i)->~Player();

players.clear();
col = 0;
row = 0;
stoppedCounter = 0;


void Scene::removeSound(Player *player)
players.removeAll(player);

if(player->getPlayer()->PlayingState == QMediaPlayer::PlayingState)
--stoppedCounter;


player->~Player();

grid->~QGridLayout();
grid = new QGridLayout;
h->insertLayout(h->count() - 1, grid);

row = 0;
col = 0;
int counter = 0;
while(counter < players.size())
if(col < 3)
grid->addWidget(players.at(counter), row, col);
++col;
else
col = 0;
++row;
grid->addWidget(players.at(counter), row, col);
++col;

++counter;

soundEnd();


void Scene::addSound(bool checked)
(void)checked;

QFileDialog fileDialog;
QStringList fileList = fileDialog.getOpenFileNames
(this, "Open MP3", QDir::currentPath(), "MP3 files (*.mp3)");

if(!fileList.isEmpty())
for(int i = 0; i < fileList.size(); ++i)
if(col < 3)
appendSound(fileList, i);
++col;
else
col = 0;
row++;
appendSound(fileList, i);
++col;


else
return;



void Scene::stopAllSounds(bool checked)
(void)checked;
for(int i = 0; i < players.size(); ++i)
players.at(i)->getPlayer()->stop();



void Scene::setEditorLayout()
col = 0;
row = 0;

CustomListWidget *listWidget = new CustomListWidget;

QVector<QString> paths = ":/Sounds/Age of Sail/", ":/Sounds/Combat (Future)/", ":/Sounds/Combat (Medieval)/",
":/Sounds/Dark Forest/", ":/Sounds/Death House", ":/Sounds/Deep Six", ":/Sounds/Dungeon",
":/Sounds/Future City", ":/Sounds/House on the Hill", ":/Sounds/Jungle Planet",
":/Sounds/Monster Pack", ":/Sounds/Olde Towne", ":/Sounds/Starship", ":/Sounds/True West",
":Sounds/Wasteland";

for(int i = 0; i < paths.size(); ++i)
QDir dir(paths.at(i));
QFileInfoList fileList = dir.entryInfoList(QDir::Files, QDir::Name);
for(int j = 0; j < fileList.size(); ++j)
listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
qDebug() << fileList.at(j).absoluteFilePath();



editor = new Editor(this);
// editor->setScene(this);
editor->setWindowFlags(Qt::Window);
editor->setWindowModality(Qt::WindowModal);
editor->setAcceptDrops(true);

connect(listWidget, &CustomListWidget::customItem, editor, &Editor::addDefaultSound);

panel = new QWidget;

add = new QPushButton;
stopAll = new QPushButton;
removeAll = new QPushButton;
editorPS = new QPushButton;
editorPS->setCheckable(true);

add->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
add->setStyleSheet("background-color: transparent;");
add->setIcon(QIcon(QPixmap(":icons/add.png")));
add->setIconSize(QSize(38, 38));
add->setToolTip("Add Mp3 Sound");
add->setToolTipDuration(500);

stopAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
stopAll->setStyleSheet("background-color: transparent;");
stopAll->setIcon(QIcon(QPixmap(":icons/stopAll.png")));
stopAll->setIconSize(QSize(38, 38));
stopAll->setToolTip("Stop All Sounds");
stopAll->setToolTipDuration(500);

removeAll->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
removeAll->setStyleSheet("background-color: transparent;");
removeAll->setIcon(QIcon(QPixmap(":icons/closeAll.png")));
removeAll->setIconSize(QSize(38, 38));
removeAll->setToolTip("Remove All Sounds");
removeAll->setToolTipDuration(500);

editorPS->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
editorPS->setStyleSheet("background-color: transparent;");
editorPS->setIcon(QIcon(QPixmap(":/icons/play.png")));
editorPS->setIconSize(QSize(28, 28));
editorPS->setToolTip("Play / Stop All Sounds");
editorPS->setToolTipDuration(500);

grid = new QGridLayout;
panelLayout = new QHBoxLayout;
h = new QHBoxLayout;
v = new QVBoxLayout;

panelLayout->addWidget(add);
panelLayout->addWidget(stopAll);
panelLayout->addWidget(removeAll);
panelLayout->addWidget(editorPS);
panelLayout->addStretch(1);

panel->setLayout(panelLayout);

h->addLayout(grid);
h->addStretch(1);

v->addWidget(panel);
v->addLayout(h);
v->addStretch(1);

QWidget *gridwidget = new QWidget;
gridwidget->setLayout(v);

QHBoxLayout *finalLayout = new QHBoxLayout;
finalLayout->addWidget(listWidget);
finalLayout->addWidget(gridwidget);

editor->setLayout(finalLayout);


void Scene::showEditor(bool checked)
(void)checked;

editor->setWindowTitle("Ambience Editor: " + ui->titleLabel->text());
editor->resize(400, 300);
editor->show();


void Scene::emitThisScene(bool checked)
(void)checked;
emit thisScene(this);


void Scene::setTitle(QString title)
ui->titleLabel->setText(title);


QPushButton* Scene::getPlayStopButton()
return ui->playStopButton;


void Scene::appendSound(QStringList list, int i)
players.append(new Player(this));
connect(players.at(players.size() - 1), &Player::thisPlayer, this, &Scene::removeSound);
connect(players.at(players.size() - 1), &Player::sliderValueChanged, this, &Scene::setMasterVolume);

/* La conexion garantiza que si no hay ningun sonido en loop dentro del editor, el boton
* de play de la Scene cambie de estado */

connect(players.at(players.size() - 1)->getPlayer(), &QMediaPlayer::stateChanged,
this, &Scene::playerStateChanged);

qDebug() << players.size() << endl;
players.at(players.size() - 1)->getPlaylist()->addMedia(QUrl(list.at(i)));
QString file = list.at(i);
file.remove(0, file.lastIndexOf('/') + 1);
file.chop(4);
players.at(players.size() - 1)->setTitle(file);
grid->addWidget(players.at(players.size() - 1), row, col);



widget.cpp



#include "widget.h"
#include "ui_widget.h"

#include "customtabwidget.h"

#include <QHBoxLayout>

#include <QDir>
#include <QFileInfoList>

Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
ui->setupUi(this);

QHBoxLayout *layout = new QHBoxLayout(this);

CustomTabWidget *tabWidget = new CustomTabWidget;

layout->addWidget(tabWidget);

this->setWindowTitle("TableTop SoundBoard v2.0");
this->resize(800, 600);


Widget::~Widget()
delete ui;









share|improve this question












share|improve this question




share|improve this question








edited Apr 7 at 4:35









Jamal♦

30.1k11114225




30.1k11114225









asked Apr 7 at 3:28









PVPJCJ

212




212











  • Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
    – yuri
    Apr 7 at 7:18










  • @yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
    – PVPJCJ
    Apr 7 at 14:44










  • A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
    – yuri
    Apr 7 at 15:14










  • @yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
    – PVPJCJ
    Apr 9 at 18:33

















  • Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
    – yuri
    Apr 7 at 7:18










  • @yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
    – PVPJCJ
    Apr 7 at 14:44










  • A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
    – yuri
    Apr 7 at 15:14










  • @yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
    – PVPJCJ
    Apr 9 at 18:33
















Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
– yuri
Apr 7 at 7:18




Have you made sure the high memory usage is your doing and not intrinsic to the framework you're using?
– yuri
Apr 7 at 7:18












@yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
– PVPJCJ
Apr 7 at 14:44




@yuri How can i make sure its not me, any particular tool or method in mind? As for now my qrc file consists of 603 sounds displayed on a custom list widget. How can this simple thing take more memory than Ubuntu 16.04 running on legacy hardware...
– PVPJCJ
Apr 7 at 14:44












A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
– yuri
Apr 7 at 15:14




A simple approach could be to run an "empty" program consisting only of code responsible for the window/widgets etc. and compare the memory usage to your normal program. You can also try memory profilers such as valgrind/massif.
– yuri
Apr 7 at 15:14












@yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
– PVPJCJ
Apr 9 at 18:33





@yuri So, tinkering a little bit testing the empty program approach i found this: listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png"))); Why passing the QIcon causes so much overhead? The memory was reduced from 1.5 GB to 40-50 mb. Working right now on Mtuner to find out more. Thx.
– PVPJCJ
Apr 9 at 18:33
















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191454%2fsoundboard-in-c-using-qt%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191454%2fsoundboard-in-c-using-qt%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?