diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..325b779 --- /dev/null +++ b/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + Tray * systemTray = new Tray(); + QQmlContext * context = engine.rootContext(); + + context->setContextProperty("systemTray", systemTray); + + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} diff --git a/main.qml b/main.qml new file mode 100644 index 0000000..daa367a --- /dev/null +++ b/main.qml @@ -0,0 +1,215 @@ +import QtQuick 2.0 +import QtQuick.Window 2.15 +import QtMultimedia 5.15 +import QtQuick.Controls 2.12 +import QtQuick.Dialogs 1.3 + + +ApplicationWindow { + id:root + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") + + property int selectedIndex: -1 + + + MediaPlayer { + id: player; + volume: volumeSlider.volume + source: url + playlist: Playlist{ + id:playlist + } + } + + ListView { + id:listview + width:parent.width/2 + height: parent.height + anchors.left: parent.left + anchors.bottom: parent.bottom + model: playlist; + spacing: 5 + delegate: Rectangle{ + width: listview.width + border.color: (model.index == root.selectedIndex) ? "red" : "gray" + height: 25 + Text { + id: songUrl + text: source + visible: true + } + Text { + id: songname + text: source + } + MouseArea{ + id:delegatemousearea + anchors.fill:parent + onClicked: { + root.selectedIndex = model.index + } + onDoubleClicked: { + playlist.moveItem(root.selectedIndex,0) + playlist.previous() + player.play() + } + } + } + } + + Label{ + id:label + anchors.bottom: progresstime.top + anchors.left: add.right + text: player.metaData.title + " " + player.metaData.albumArtist + } + Image { + id: songImage + height: parent.height-next.height-add.height-label.height-progresstime.height + width: parent.width-listview.width + anchors.bottom: label.top + anchors.right: pause.right + source: (player.metaData.posterUrl!=="undefind")?"qrc:/png-transparent-color-drawing-headphones-illustration-musical-note-game-photography-stage.png":player.metaData.posterUrl +} + FileDialog{ + id:add_File + nameFilters: ["Song files(*.mp3)"] + onAccepted: { + playlist.addItem(fileUrl); + } + } + + Button{ + id:add + text: "add" + anchors.bottom: privious.top + anchors.right: privious.right + anchors.bottomMargin: 5 + onClicked: { + add_File.open() + } + } + Button{ + id:privious + text:"privious" + anchors.right: play.left + anchors.bottom: parent.bottom + anchors.rightMargin: 5 + onClicked: { + playlist.previous(); + } + } + + Button{ + id:next + text: "next" + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.rightMargin: 5 + onClicked: { + playlist.next(); + } + } + Button{ + id:play + text: "play" + anchors.right: pause.left + anchors.rightMargin: 5 + anchors.bottom: parent.bottom + onClicked: { + player.play(); + } + } + Button{ + id:pause + text: "pause" + anchors.right: next.left + anchors.rightMargin: 5 + anchors.bottom: parent.bottom + onClicked: { + player.pause(); + } + } + Slider { + id: volumeSlider + anchors.left: add.right + anchors.bottom: add.bottom + anchors.leftMargin: 5 + property real volume: QtMultimedia.convertVolume(volumeSlider.value, + QtMultimedia.LogarithmicVolumeScale, + QtMultimedia.LinearVolumeScale) + } + Slider{ + id:progresstime + anchors.bottom: volumeSlider.top + anchors.left: add.left + anchors.right: next.right + from: 0 + to: player.duration + stepSize: 1000 + + onPressedChanged: { + if (!pressed && player.seekable) + player.seek(progresstime.value) + } + + Connections{ + target: player + onPositionChanged:{ + progresstime.value=player.position + if(progresstime.value==0 && root.visibility === Window.Hidden) + systemTray.messege("Сейчас играет",player.metaData.title) + } + } + + } + + property bool ignoreCheck: false + + /* С помощью объекта Connections + * Устанавливаем соединение с классом системного трея + * */ + Connections { + target: systemTray + // Сигнал - показать окно + onSignalShow: { + root.show(); + } + + // Сигнал - закрыть приложения игнорируя чек-бокс + onSignalQuit: { + ignoreCheck = true + close(); + } + + // Свернуть/развернуть окно через клик по системному трею + onSignalIconActivated: { + if(root.visibility == Window.Hidden) { + root.show() + } else { + root.hide() + } + } + } + + + // Обработчик события закрытия окна + onClosing: { + /* Если чекбокс не должен игнорироваться и он активен, + * то скрываем приложение. + * В противном случае закрываем приложение + * */ + if(ignoreCheck === false){ + close.accepted = false + root.hide() + } else { + // Завершаем приложение + Qt.quit() + } + } + + } + diff --git a/play-button.png b/play-button.png new file mode 100644 index 0000000..7238aba Binary files /dev/null and b/play-button.png differ diff --git a/png-transparent-color-drawing-headphones-illustration-musical-note-game-photography-stage.png b/png-transparent-color-drawing-headphones-illustration-musical-note-game-photography-stage.png new file mode 100644 index 0000000..c0572eb Binary files /dev/null and b/png-transparent-color-drawing-headphones-illustration-musical-note-game-photography-stage.png differ diff --git a/qml.qrc b/qml.qrc new file mode 100644 index 0000000..3387421 --- /dev/null +++ b/qml.qrc @@ -0,0 +1,7 @@ + + + main.qml + play-button.png + png-transparent-color-drawing-headphones-illustration-musical-note-game-photography-stage.png + + diff --git a/tray.cpp b/tray.cpp new file mode 100644 index 0000000..fef5f9f --- /dev/null +++ b/tray.cpp @@ -0,0 +1,59 @@ +#include "tray.h" +#include +#include + +Tray::Tray(QObject *parent) : QObject(parent) +{ + + // Создаём контекстное меню с двумя пунктами + QMenu *trayIconMenu = new QMenu(); + + QAction * viewWindow = new QAction(trUtf8("Развернуть окно"), this); + QAction * quitAction = new QAction(trUtf8("Выход"), this); + + /* подключаем сигналы нажатий на пункты меню к соответсвующим сигналам для QML. + * */ + connect(viewWindow, &QAction::triggered, this, &Tray::signalShow); + connect(quitAction, &QAction::triggered, this, &Tray::signalQuit); + + trayIconMenu->addAction(viewWindow); + trayIconMenu->addAction(quitAction); + + /* Инициализируем иконку трея, устанавливаем иконку, + * а также задаем всплывающую подсказку + * */ + trayIcon = new QSystemTrayIcon(); + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setIcon(QIcon(":/play-button.png")); + trayIcon->show(); + trayIcon->setToolTip("Tray Program" "\n" + "Работа со сворачиванием программы трей"); + + /* Также подключаем сигнал нажатия на иконку к обработчику + * данного нажатия + * */ + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); +} + +/* Метод, который обрабатывает нажатие на иконку приложения в трее + * */ +void Tray::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + switch (reason){ + case QSystemTrayIcon::Trigger: + // В случае сигнала нажатия на иконку трея вызываем сигнал в QML слой + emit signalIconActivated(); + break; + default: + break; + } +} + +void Tray::hideIconTray() +{ + trayIcon->hide(); +} +void Tray::messege(QString title,QString messege){ + trayIcon->showMessage(title,messege,QSystemTrayIcon::Information,500); +} diff --git a/tray.h b/tray.h new file mode 100644 index 0000000..bee70db --- /dev/null +++ b/tray.h @@ -0,0 +1,37 @@ +#ifndef TRAY_H +#define TRAY_H + +#include +#include +#include +#include +#include + +class Tray : public QObject +{ + Q_OBJECT +public: + explicit Tray(QObject *parent = 0); + + // Сигналы от системного трея +signals: + void signalIconActivated(); + void signalShow(); + void signalQuit(); + +private slots: + /* Слот, который будет принимать сигнал от события + * нажатия на иконку приложения в трее + */ + void iconActivated(QSystemTrayIcon::ActivationReason reason); + +public slots: + void hideIconTray(); + void messege(QString title,QString messege); + +private: + /* Объявляем объект будущей иконки приложения для трея */ + QSystemTrayIcon * trayIcon; +}; + +#endif // TRAY_H