diff --git a/utils/audio_visualizer.py b/components/AudioVisualizer.py
similarity index 71%
rename from utils/audio_visualizer.py
rename to components/AudioVisualizer.py
index 7313938..417018a 100644
--- a/utils/audio_visualizer.py
+++ b/components/AudioVisualizer.py
@@ -1,10 +1,17 @@
-from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5 import QtWidgets
import numpy as np
-from .fft_analyser import FFTAnalyser
+from utils import FFTAnalyser
class AudioVisualizer(QtWidgets.QWidget):
+ """_Audio Visualizer component_
+ Args:
+ QtWidgets (_type_): _description_
+
+ Returns:
+ _type_: _description_
+ """
def __init__(self, media_player):
super().__init__()
self.media_player = media_player
diff --git a/components/MusicTable.py b/components/MusicTable.py
index 2ca97c2..715038e 100644
--- a/components/MusicTable.py
+++ b/components/MusicTable.py
@@ -1,16 +1,17 @@
import DBA
from PyQt5.QtGui import QStandardItem, QStandardItemModel
-from PyQt5.QtWidgets import QTableView, QApplication
+from PyQt5.QtWidgets import QTableView
from PyQt5.QtCore import QTimer
from tinytag import TinyTag
+from utils import add_files_to_library
+from utils import get_id3_tags
+import logging
class MusicTable(QTableView):
def __init__(self, parent=None, qapp=None):
QTableView.__init__(self, parent)
self.headers = ['title', 'artist', 'album', 'genre', 'codec', 'year', 'path']
- self.model = QStandardItemModel()
- self.model.setHorizontalHeaderLabels(self.headers)
self.songChanged = None
self.selected_song_filepath = None
self.current_song_filepath = None
@@ -56,6 +57,9 @@ class MusicTable(QTableView):
"""Sets the filepath of the currently selected song"""
self.selected_song_filepath = self.currentIndex().siblingAtColumn(self.headers.index('path')).data()
print(f'Selected song: {self.selected_song_filepath}')
+ print('TAGS:')
+ print(get_id3_tags(self.selected_song_filepath))
+ print('END TAGS')
def set_current_song_filepath(self):
"""Sets the filepath of the currently playing/chosen song"""
@@ -80,6 +84,9 @@ class MusicTable(QTableView):
def fetch_library(self):
+ """Initialize the tableview model"""
+ self.model = QStandardItemModel()
+ self.model.setHorizontalHeaderLabels(self.headers)
# Fetch library data
with DBA.DBAccess() as db:
data = db.query('SELECT title, artist, album, genre, codec, album_date, filepath FROM library;', ())
@@ -89,6 +96,20 @@ class MusicTable(QTableView):
self.model.appendRow(items)
# Set the model to the tableView (we are the tableview)
self.setModel(self.model)
+ self.update()
+
+ def add_files(self, files):
+ """When song(s) added to the library, update the tableview model
+ - Drag & Drop song(s) on tableView
+ - File > Open > List of song(s)
+ """
+ print(f'tableView - adding files: {files}')
+ response = add_files_to_library(files)
+ if response:
+ self.fetch_library()
+ else:
+ logging.warning('MusicTable.add_files | failed to add files to library')
+
def load_qapp(self, qapp):
self.qapp = qapp
diff --git a/components/__init__.py b/components/__init__.py
index 706d493..dbbdfbf 100644
--- a/components/__init__.py
+++ b/components/__init__.py
@@ -1 +1,2 @@
-from .MusicTable import MusicTable
\ No newline at end of file
+from .MusicTable import MusicTable
+from .AudioVisualizer import AudioVisualizer
\ No newline at end of file
diff --git a/main.py b/main.py
index 5d29ef6..c1b1976 100644
--- a/main.py
+++ b/main.py
@@ -2,15 +2,16 @@ import DBA
from ui import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow, QApplication
import qdarktheme
-from PyQt5.QtCore import QUrl, QTimer, QFile, QTextStream
+from PyQt5.QtCore import QUrl, QTimer, QEvent
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe
-from PyQt5.QtGui import QStandardItem, QStandardItemModel
from utils import scan_for_music
from utils import initialize_library_database
-from utils import AudioVisualizer
+from components import AudioVisualizer
from pyqtgraph import mkBrush
-from components import MusicTable
+import configparser
+# Create ui.py file from Qt Designer
+# pyuic5 ui.ui -o ui.py
class ApplicationWindow(QMainWindow, Ui_MainWindow):
def __init__(self, qapp):
@@ -23,6 +24,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.qapp = qapp
print(f'ApplicationWindow self.qapp: {self.qapp}')
self.tableView.load_qapp(self.qapp)
+ self.config = configparser.ConfigParser()
+ self.config.read('config.ini')
global stopped
stopped = False
@@ -64,12 +67,51 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
# self.pauseButton.clicked.connect(self.on_pause_clicked)
self.previousButton.clicked.connect(self.on_previous_clicked) # Click to previous song
self.nextButton.clicked.connect(self.on_next_clicked) # Click to next song
- # self.tableView.clicked.connect(self.set_clicked_cell_filepath)
self.actionPreferences.triggered.connect(self.actionPreferencesClicked) # Open preferences menu
self.actionScanLibraries.triggered.connect(self.scan_libraries) # Scan library
self.actionClearDatabase.triggered.connect(initialize_library_database) # Clear database
+ ## tableView
+ # self.tableView.clicked.connect(self.set_clicked_cell_filepath)
self.tableView.doubleClicked.connect(self.play_audio_file) # Double click to play song
+ self.tableView.viewport().installEventFilter(self) # for drag & drop functionality
+ # self.tableView.model.layoutChanged()
+ ### set column widths
+ table_view_column_widths = str(self.config['table']['column_widths']).split(',')
+ for i in range(self.tableView.model.columnCount()):
+ self.tableView.setColumnWidth(i, int(table_view_column_widths[i]))
+ def eventFilter(self, source, event):
+ """Handles events"""
+ # tableView (drag & drop)
+ if (source is self.tableView.viewport() and
+ (event.type() == QEvent.DragEnter or
+ event.type() == QEvent.DragMove or
+ event.type() == QEvent.Drop) and
+ event.mimeData().hasUrls()):
+ files = []
+ if event.type() == QEvent.Drop:
+ for url in event.mimeData().urls():
+ if url.isLocalFile():
+ files.append(url.path())
+ self.tableView.add_files(files)
+ event.accept()
+ return True
+ return super().eventFilter(source, event)
+
+ def closeEvent(self, event):
+ """Save settings when closing the application"""
+ # MusicTable/tableView column widths
+ list_of_column_widths = []
+ for i in range(self.tableView.model.columnCount()):
+ list_of_column_widths.append(str(self.tableView.columnWidth(i)))
+ column_widths_as_string = ','.join(list_of_column_widths)
+ self.config['table']['column_widths'] = column_widths_as_string
+
+
+ # Save the config
+ with open('config.ini', 'w') as configfile:
+ self.config.write(configfile)
+ super().closeEvent(event)
def play_audio_file(self):
"""Start playback of selected track & moves playback slider"""
diff --git a/requirements.txt b/requirements.txt
index 75046f5..51fea21 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-tinytag
+mutagen
matplotlib
pyqt5
pydub
diff --git a/sample_config.ini b/sample_config.ini
index 725aed2..74fa845 100644
--- a/sample_config.ini
+++ b/sample_config.ini
@@ -9,4 +9,8 @@ reorganize_destination = /where/to/reorganize/to
[settings]
# Which file types are scanned
-extensions = mp3,wav,ogg,flac
\ No newline at end of file
+extensions = mp3,wav,ogg,flac
+
+[table]
+# Music table column widths
+column_widths = 181,116,222,76,74,72,287
\ No newline at end of file
diff --git a/ui.py b/ui.py
index cbcd2d4..eced834 100644
--- a/ui.py
+++ b/ui.py
@@ -18,32 +18,13 @@ class Ui_MainWindow(object):
MainWindow.setStatusTip("")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
- self.frame = QtWidgets.QFrame(self.centralwidget)
- self.frame.setGeometry(QtCore.QRect(0, 160, 1061, 461))
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
- self.frame.setSizePolicy(sizePolicy)
- self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame.setObjectName("frame")
- self.tableView = MusicTable(self.frame)
- self.tableView.setGeometry(QtCore.QRect(0, 0, 1061, 461))
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.tableView.sizePolicy().hasHeightForWidth())
- self.tableView.setSizePolicy(sizePolicy)
- self.tableView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
- self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
- self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.AnyKeyPressed|QtWidgets.QAbstractItemView.EditKeyPressed)
- self.tableView.setAlternatingRowColors(True)
- self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
- self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
- self.tableView.setObjectName("tableView")
- self.tableView.verticalHeader().setVisible(False)
- self.frame_2 = QtWidgets.QFrame(self.centralwidget)
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.centralwidget)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.frame_6 = QtWidgets.QFrame(self.centralwidget)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.frame_2 = QtWidgets.QFrame(self.frame_6)
self.frame_2.setGeometry(QtCore.QRect(0, 0, 161, 161))
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -51,26 +32,7 @@ class Ui_MainWindow(object):
self.albumGraphicsView = QtWidgets.QGraphicsView(self.frame_2)
self.albumGraphicsView.setGeometry(QtCore.QRect(0, 0, 161, 161))
self.albumGraphicsView.setObjectName("albumGraphicsView")
- self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
- self.horizontalLayoutWidget.setGeometry(QtCore.QRect(540, 0, 521, 41))
- self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
- self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
- self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.playbackSlider = QtWidgets.QSlider(self.horizontalLayoutWidget)
- self.playbackSlider.setOrientation(QtCore.Qt.Horizontal)
- self.playbackSlider.setObjectName("playbackSlider")
- self.horizontalLayout.addWidget(self.playbackSlider)
- self.startTimeLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
- self.startTimeLabel.setObjectName("startTimeLabel")
- self.horizontalLayout.addWidget(self.startTimeLabel)
- self.slashLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
- self.slashLabel.setObjectName("slashLabel")
- self.horizontalLayout.addWidget(self.slashLabel)
- self.endTimeLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
- self.endTimeLabel.setObjectName("endTimeLabel")
- self.horizontalLayout.addWidget(self.endTimeLabel)
- self.frame_4 = QtWidgets.QFrame(self.centralwidget)
+ self.frame_4 = QtWidgets.QFrame(self.frame_6)
self.frame_4.setGeometry(QtCore.QRect(540, 40, 521, 121))
self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -78,18 +40,7 @@ class Ui_MainWindow(object):
self.PlotWidget = PlotWidget(self.frame_4)
self.PlotWidget.setGeometry(QtCore.QRect(0, 0, 521, 121))
self.PlotWidget.setObjectName("PlotWidget")
- self.frame_3 = QtWidgets.QFrame(self.centralwidget)
- self.frame_3.setGeometry(QtCore.QRect(0, 680, 1061, 61))
- self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame_3.setObjectName("frame_3")
- self.volumeSlider = QtWidgets.QSlider(self.frame_3)
- self.volumeSlider.setGeometry(QtCore.QRect(10, 10, 181, 31))
- self.volumeSlider.setMaximum(100)
- self.volumeSlider.setProperty("value", 50)
- self.volumeSlider.setOrientation(QtCore.Qt.Horizontal)
- self.volumeSlider.setObjectName("volumeSlider")
- self.frame_5 = QtWidgets.QFrame(self.centralwidget)
+ self.frame_5 = QtWidgets.QFrame(self.frame_6)
self.frame_5.setGeometry(QtCore.QRect(160, 0, 381, 161))
self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -123,30 +74,99 @@ class Ui_MainWindow(object):
self.albumLabel.setFont(font)
self.albumLabel.setObjectName("albumLabel")
self.verticalLayout.addWidget(self.albumLabel)
- self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.centralwidget)
- self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(0, 620, 1061, 60))
- self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
- self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayoutWidget = QtWidgets.QWidget(self.frame_6)
+ self.horizontalLayoutWidget.setGeometry(QtCore.QRect(540, 0, 521, 41))
+ self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.playbackSlider = QtWidgets.QSlider(self.horizontalLayoutWidget)
+ self.playbackSlider.setOrientation(QtCore.Qt.Horizontal)
+ self.playbackSlider.setObjectName("playbackSlider")
+ self.horizontalLayout.addWidget(self.playbackSlider)
+ self.startTimeLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
+ self.startTimeLabel.setObjectName("startTimeLabel")
+ self.horizontalLayout.addWidget(self.startTimeLabel)
+ self.slashLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
+ self.slashLabel.setObjectName("slashLabel")
+ self.horizontalLayout.addWidget(self.slashLabel)
+ self.endTimeLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
+ self.endTimeLabel.setObjectName("endTimeLabel")
+ self.horizontalLayout.addWidget(self.endTimeLabel)
+ self.verticalLayout_3.addWidget(self.frame_6)
+ self.frame = QtWidgets.QFrame(self.centralwidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+ self.frame.setSizePolicy(sizePolicy)
+ self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.frame)
+ self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(0, 0, 1061, 461))
+ self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
+ self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.tableView = MusicTable(self.verticalLayoutWidget_2)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(1)
+ sizePolicy.setVerticalStretch(1)
+ sizePolicy.setHeightForWidth(self.tableView.sizePolicy().hasHeightForWidth())
+ self.tableView.setSizePolicy(sizePolicy)
+ self.tableView.setMaximumSize(QtCore.QSize(32000, 32000))
+ self.tableView.setAcceptDrops(True)
+ self.tableView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+ self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
+ self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.AnyKeyPressed|QtWidgets.QAbstractItemView.EditKeyPressed)
+ self.tableView.setAlternatingRowColors(True)
+ self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
+ self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
+ self.tableView.setSortingEnabled(True)
+ self.tableView.setObjectName("tableView")
+ self.tableView.horizontalHeader().setCascadingSectionResizes(True)
+ self.tableView.horizontalHeader().setStretchLastSection(True)
+ self.tableView.verticalHeader().setVisible(False)
+ self.verticalLayout_2.addWidget(self.tableView)
+ self.verticalLayout_3.addWidget(self.frame)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
- self.previousButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+ self.previousButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(28)
self.previousButton.setFont(font)
self.previousButton.setObjectName("previousButton")
self.horizontalLayout_2.addWidget(self.previousButton)
- self.playButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+ self.playButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(28)
self.playButton.setFont(font)
self.playButton.setObjectName("playButton")
self.horizontalLayout_2.addWidget(self.playButton)
- self.nextButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
+ self.nextButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(28)
self.nextButton.setFont(font)
self.nextButton.setObjectName("nextButton")
self.horizontalLayout_2.addWidget(self.nextButton)
+ self.verticalLayout_3.addLayout(self.horizontalLayout_2)
+ self.frame_3 = QtWidgets.QFrame(self.centralwidget)
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.volumeSlider = QtWidgets.QSlider(self.frame_3)
+ self.volumeSlider.setGeometry(QtCore.QRect(10, 10, 181, 31))
+ self.volumeSlider.setMaximum(100)
+ self.volumeSlider.setProperty("value", 50)
+ self.volumeSlider.setOrientation(QtCore.Qt.Horizontal)
+ self.volumeSlider.setObjectName("volumeSlider")
+ self.verticalLayout_3.addWidget(self.frame_3)
+ self.verticalLayout_3.setStretch(0, 3)
+ self.verticalLayout_3.setStretch(1, 8)
+ self.verticalLayout_3.setStretch(2, 1)
+ self.verticalLayout_3.setStretch(3, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1062, 24))
@@ -183,12 +203,12 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
- self.startTimeLabel.setText(_translate("MainWindow", "00:00"))
- self.slashLabel.setText(_translate("MainWindow", "/"))
- self.endTimeLabel.setText(_translate("MainWindow", "00:00"))
self.artistLabel.setText(_translate("MainWindow", "artist"))
self.titleLabel.setText(_translate("MainWindow", "song title"))
self.albumLabel.setText(_translate("MainWindow", "album"))
+ self.startTimeLabel.setText(_translate("MainWindow", "00:00"))
+ self.slashLabel.setText(_translate("MainWindow", "/"))
+ self.endTimeLabel.setText(_translate("MainWindow", "00:00"))
self.previousButton.setText(_translate("MainWindow", "⏮️"))
self.playButton.setText(_translate("MainWindow", "▶️"))
self.nextButton.setText(_translate("MainWindow", "⏭️"))
diff --git a/ui.ui b/ui.ui
index 0e7da19..3b7210a 100644
--- a/ui.ui
+++ b/ui.ui
@@ -17,309 +17,328 @@
-
-
-
- 0
- 160
- 1061
- 461
-
-
-
-
- 0
- 0
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 0
- 0
- 1061
- 461
-
-
-
-
- 0
- 0
-
-
-
- Qt::ScrollBarAlwaysOff
-
-
- QAbstractScrollArea::AdjustToContents
-
-
- QAbstractItemView::AnyKeyPressed|QAbstractItemView::EditKeyPressed
-
-
- true
-
-
- QAbstractItemView::ExtendedSelection
-
-
- QAbstractItemView::SelectRows
-
-
- false
-
-
-
-
-
-
- 0
- 0
- 161
- 161
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 0
- 0
- 161
- 161
-
-
-
-
-
-
-
- 540
- 0
- 521
- 41
-
-
-
- -
-
-
- Qt::Horizontal
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 161
+ 161
+
-
-
- -
-
-
- 00:00
+
+ QFrame::StyledPanel
-
-
- -
-
-
- /
+
+ QFrame::Raised
+
+
+
+ 0
+ 0
+ 161
+ 161
+
+
+
-
- -
-
-
- 00:00
+
+
+
+ 540
+ 40
+ 521
+ 121
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 521
+ 121
+
+
+
-
-
-
-
-
-
- 540
- 40
- 521
- 121
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 0
- 0
- 521
- 121
-
-
-
-
-
-
-
- 0
- 680
- 1061
- 61
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 10
- 10
- 181
- 31
-
-
-
- 100
-
-
- 50
-
-
- Qt::Horizontal
-
-
-
-
-
-
- 160
- 0
- 381
- 161
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 0
- 0
- 381
- 161
-
-
-
+
+
+
+ 160
+ 0
+ 381
+ 161
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 381
+ 161
+
+
+
+ -
+
+
+
+ 24
+ 75
+ true
+
+
+
+ artist
+
+
+
+ -
+
+
+
+ 18
+
+
+
+ song title
+
+
+
+ -
+
+
+
+ 16
+ 50
+ true
+ false
+
+
+
+ album
+
+
+
+
+
+
+
+
+
+ 540
+ 0
+ 521
+ 41
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 00:00
+
+
+
+ -
+
+
+ /
+
+
+
+ -
+
+
+ 00:00
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 1061
+ 461
+
+
+
+
+ QLayout::SetNoConstraint
+
+
-
+
+
+
+ 1
+ 1
+
+
+
+
+ 32000
+ 32000
+
+
+
+ true
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ QAbstractScrollArea::AdjustToContents
+
+
+ QAbstractItemView::AnyKeyPressed|QAbstractItemView::EditKeyPressed
+
+
+ true
+
+
+ QAbstractItemView::ExtendedSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+ -
+
-
-
+
- 24
- 75
- true
+ 28
- artist
+ ⏮️
-
-
+
- 18
+ 28
- song title
+ ▶️
-
-
+
- 16
- 50
- true
- false
+ 28
- album
+ ⏭️
-
-
-
-
-
- 0
- 620
- 1061
- 60
-
-
-
- -
-
-
-
- 28
-
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 10
+ 10
+ 181
+ 31
+
-
- ⏮️
+
+ 100
+
+
+ 50
+
+
+ Qt::Horizontal
-
- -
-
-
-
- 28
-
-
-
- ▶️
-
-
-
- -
-
-
-
- 28
-
-
-
- ⏭️
-
-
-
-
-
+
+
+