Initial Commit für ML Playground
@ -0,0 +1,46 @@
|
|||||||
|
# Read WAV and MP3 files to array
|
||||||
|
from pydub import AudioSegment
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
#from scipy.io import wavfile
|
||||||
|
#from plotly.offline import init_notebook_mode
|
||||||
|
#import plotly.graph_objs as go
|
||||||
|
#import plotly
|
||||||
|
import sklearn
|
||||||
|
import IPython
|
||||||
|
from IPython.display import Image
|
||||||
|
import librosa
|
||||||
|
import librosa.display
|
||||||
|
#import eli5
|
||||||
|
#import logguru
|
||||||
|
|
||||||
|
import os
|
||||||
|
import warnings
|
||||||
|
warnings.filterwarnings('ignore')
|
||||||
|
|
||||||
|
path=os.path.dirname(__file__)
|
||||||
|
os.chdir(path)
|
||||||
|
sampleFolder = os.path.join(path, 'AudioSamples')
|
||||||
|
sampleList = os.listdir(sampleFolder)
|
||||||
|
for sample_fileName in sampleList:
|
||||||
|
print(sample_fileName)
|
||||||
|
#print(sampleList[0])
|
||||||
|
filepath = os.path.join(sampleFolder,sample_fileName)
|
||||||
|
#filepath = os.path.join(sampleFolder,sampleList[0])
|
||||||
|
y,sr = librosa.load(filepath,duration=2.97)
|
||||||
|
ps = librosa.feature.melspectrogram(y=y, sr=sr)
|
||||||
|
#print(ps.shape)
|
||||||
|
#print(ps)
|
||||||
|
#print(y)
|
||||||
|
##verschiedene spectral anzeigen
|
||||||
|
#librosa.display.specshow(ps,y_axis='mel',x_axis='time')
|
||||||
|
|
||||||
|
#librosa.display.waveplot(ps, sr=sr)
|
||||||
|
|
||||||
|
X = librosa.stft(y)
|
||||||
|
Xdb = librosa.amplitude_to_db(abs(X))
|
||||||
|
plt.figure(figsize=(14,5))
|
||||||
|
librosa.display.specshow(Xdb,sr=sr,x_axis='time',y_axis='hz')
|
||||||
|
|
||||||
|
plt.show()
|
@ -0,0 +1,95 @@
|
|||||||
|
# Read WAV and MP3 files to array
|
||||||
|
from pydub import AudioSegment
|
||||||
|
import numpy as np
|
||||||
|
from scipy.io import wavfile
|
||||||
|
from plotly.offline import init_notebook_mode
|
||||||
|
import plotly.graph_objs as go
|
||||||
|
import plotly
|
||||||
|
import IPython
|
||||||
|
import librosa
|
||||||
|
|
||||||
|
# read WAV file using scipy.io.wavfile
|
||||||
|
#fs_wav, data_wav = wavfile.read("F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\AudioSamples\FF8-Odeka Ke Chocobo.wav")
|
||||||
|
#time_wav = np.arange(0, len(data_wav)) / fs_wav
|
||||||
|
#plotly.offline.iplot({ "data": [go.Scatter(x=time_wav,
|
||||||
|
# y=data_wav[:, 0],
|
||||||
|
# name='left channel'),
|
||||||
|
# go.Scatter(x=time_wav,
|
||||||
|
# y=data_wav[:, 1],
|
||||||
|
# name='right channel')]})
|
||||||
|
|
||||||
|
# Normalization
|
||||||
|
#fs_wav, data_wav = wavfile.read("data/lost_highway_small.wav")
|
||||||
|
#data_wav_norm = data_wav / (2**15)
|
||||||
|
#time_wav = np.arange(0, len(data_wav)) / fs_wav
|
||||||
|
#plotly.offline.iplot({ "data": [go.Scatter(x=time_wav,
|
||||||
|
# y=data_wav_norm,
|
||||||
|
# name='normalized audio signal')]})
|
||||||
|
|
||||||
|
# Trim (segment) audio signal (2 seconds)
|
||||||
|
#data_wav_norm_crop = data_wav_norm[2 * fs_wav: 4 * fs_wav]
|
||||||
|
#time_wav_crop = np.arange(0, len(data_wav)) / fs_wav
|
||||||
|
#plotly.offline.iplot({ "data": [go.Scatter(x=time_wav_crop,
|
||||||
|
# y=data_wav_norm_crop,
|
||||||
|
# name='cropped audio signal')]})
|
||||||
|
|
||||||
|
# Fix-sized segmentation (breaks a signal into non-overlapping segments)
|
||||||
|
#fs, signal = wavfile.read("data/obama.wav")
|
||||||
|
#signal = signal / (2**15)
|
||||||
|
#signal_len = len(signal)
|
||||||
|
#segment_size_t = 1 # segment size in seconds
|
||||||
|
#segment_size = segment_size_t * fs # segment size in samples
|
||||||
|
## Break signal into list of segments in a single-line Python code
|
||||||
|
#segments = np.array([signal[x:x + segment_size] for x in
|
||||||
|
# np.arange(0, signal_len, segment_size)])
|
||||||
|
## Save each segment in a seperate filename
|
||||||
|
#for iS, s in enumerate(segments):
|
||||||
|
# wavfile.write("data/obama_segment_{0:d}_{1:d}.wav".format(segment_size_t * iS,
|
||||||
|
# segment_size_t * (iS + 1)), fs, (s))
|
||||||
|
|
||||||
|
|
||||||
|
## Remove pauses using an energy threshold = 50% of the median energy:
|
||||||
|
#energies = [(s**2).sum() / len(s) for s in segments]
|
||||||
|
## (attention: integer overflow would occure without normalization here!)
|
||||||
|
#thres = 0.5 * np.median(energies)
|
||||||
|
#index_of_segments_to_keep = (np.where(energies > thres)[0])
|
||||||
|
## get segments that have energies higher than a the threshold:
|
||||||
|
#segments2 = segments[index_of_segments_to_keep]
|
||||||
|
## concatenate segments to signal:
|
||||||
|
#new_signal = np.concatenate(segments2)
|
||||||
|
## and write to file:
|
||||||
|
#wavfile.write("data/obama_processed.wav", fs, new_signal)
|
||||||
|
#plotly.offline.iplot({ "data": [go.Scatter(y=energies, name="energy"),
|
||||||
|
# go.Scatter(y=np.ones(len(energies)) * thres,
|
||||||
|
# name="thres")]})
|
||||||
|
# play the initial and the generated files in notebook:
|
||||||
|
#IPython.display.display(IPython.display.Audio("data/obama.wav"))
|
||||||
|
#IPython.display.display(IPython.display.Audio("data/obama_processed.wav"))
|
||||||
|
|
||||||
|
# read MP3 file using pudub
|
||||||
|
#audiofile = AudioSegment.from_file("F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\AudioSamples\FF8-Odeka Ke Chocobo.mp3")
|
||||||
|
#data_mp3 = np.array(audiofile.get_array_of_samples())
|
||||||
|
#fs_mp3 = audiofile.frame_rate
|
||||||
|
|
||||||
|
#print("juhu")
|
||||||
|
#print('Sq Error Between mp3 and wav data = {}'.format(((data_mp3 - data_wav)**2).sum()))
|
||||||
|
#print('Signal Duration = {} seconds'.format(data_wav.shape[0] / fs_wav))
|
||||||
|
|
||||||
|
# load file and extract tempo and beats:
|
||||||
|
[Fs, s] = wavfile.read('F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\AudioSamples\FF8-Odeka Ke Chocobo_mono.wav')
|
||||||
|
tempo, beats = librosa.beat.beat_track(y=s.astype('float'), sr=Fs, units="time")
|
||||||
|
beats -= 0.05
|
||||||
|
# add small 220Hz sounds on the 2nd channel of the song ON EACH BEAT
|
||||||
|
s = s.reshape(-1, 1)
|
||||||
|
s = np.array(np.concatenate((s, np.zeros(s.shape)), axis=1))
|
||||||
|
for ib, b in enumerate(beats):
|
||||||
|
t = np.arange(0, 0.2, 1.0 / Fs)
|
||||||
|
amp_mod = 0.2 / (np.sqrt(t)+0.2) - 0.2
|
||||||
|
amp_mod[amp_mod < 0] = 0
|
||||||
|
x = s.max() * np.cos(2 * np.pi * t * 220) * amp_mod
|
||||||
|
s[int(Fs * b):
|
||||||
|
int(Fs * b) + int(x.shape[0]), 1] = x.astype('int16')
|
||||||
|
# write a wav file where the 2nd channel has the estimated tempo:
|
||||||
|
wavfile.write("F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\AudioSamples\FF8-Odeka Ke Chocobo_mono.wav", Fs, np.int16(s))
|
||||||
|
# play the generated file in notebook:
|
||||||
|
IPython.display.display(IPython.display.Audio("F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\AudioSamples\FF8-Odeka Ke Chocobo_mono.wav"))
|
@ -0,0 +1,39 @@
|
|||||||
|
#########################
|
||||||
|
###
|
||||||
|
### GUI gestütztes Audio Analyse/Prediction
|
||||||
|
### ML-Programm.
|
||||||
|
### Features:
|
||||||
|
### - Download Audio/Video Daten von (legitimen) URLs
|
||||||
|
### - Setzen/Markieren von präferenz-Gewichtung bei Audio passagen
|
||||||
|
### - Lernen er Präferenzgewichtung durch CNN
|
||||||
|
### - Vorhersagen von Präferenzprofilen bei neuer Audio
|
||||||
|
### - Automatisierte Verarbeitung ganzer Playlists
|
||||||
|
###
|
||||||
|
##########################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from PyQt5.QtCore import *
|
||||||
|
from PyQt5.QtGui import *
|
||||||
|
from PyQt5.QtWidgets import *
|
||||||
|
|
||||||
|
class window(QWidget):
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super(window, self).__init__(parent)
|
||||||
|
self.resize(400,50)
|
||||||
|
self.setWindowTitle("DXM Bragi")
|
||||||
|
self.label = QLabel(self)
|
||||||
|
self.label.setText("Hello World")
|
||||||
|
font = QFont()
|
||||||
|
font.setFamily("Arial")
|
||||||
|
font.setPointSize(16)
|
||||||
|
self.label.setFont(font)
|
||||||
|
self.label.move(50,20)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
ex = window()
|
||||||
|
ex.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,579 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import shutil
|
||||||
|
import errno
|
||||||
|
from collections import OrderedDict
|
||||||
|
from functools import partial
|
||||||
|
from pytube import Playlist, YouTube, exceptions
|
||||||
|
|
||||||
|
from DXMB_ui import Ui_dxmb
|
||||||
|
from YTVidItem import QYTVidItem
|
||||||
|
|
||||||
|
from PyQt5 import QtCore as qtc
|
||||||
|
from PyQt5 import QtWidgets as qtw
|
||||||
|
from PyQt5 import QtGui as qtg
|
||||||
|
|
||||||
|
import resources
|
||||||
|
|
||||||
|
##ToolKlasse ButtonManager (Für SongbookTab)
|
||||||
|
class BTN_MANAGER():
|
||||||
|
def copyAtoB(self,sourcePath_list,targetPath_list):#done
|
||||||
|
# Pro SourcePath immer jeweils ein targetPath auch wenn das gleicher ort ist -> sonst error(oft permission error)
|
||||||
|
#print("BTN Man: CopyAtoB")
|
||||||
|
|
||||||
|
if len(sourcePath_list) != len(targetPath_list):
|
||||||
|
print("Error: Path Count mismatch")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
for index in range(0,len(sourcePath_list)) :
|
||||||
|
sourcePath = sourcePath_list[index]
|
||||||
|
targetPath = targetPath_list[index]
|
||||||
|
|
||||||
|
try:
|
||||||
|
shutil.copytree(sourcePath,targetPath,dirs_exist_ok=True)
|
||||||
|
except OSError as e:
|
||||||
|
# If the error was caused because the source wasn't a directory
|
||||||
|
if e.errno == errno.ENOTDIR:
|
||||||
|
shutil.copy(sourcePath,targetPath)
|
||||||
|
else:
|
||||||
|
print('Directory not copied. Error: %s' % e)
|
||||||
|
except PermissionError:
|
||||||
|
print("PermissionError. Try function in admin-role!")
|
||||||
|
except Exception as e:
|
||||||
|
try:
|
||||||
|
print("Error: {}".format(e.what()))
|
||||||
|
except:
|
||||||
|
print("Unknown Error.")
|
||||||
|
|
||||||
|
def moveAtoB(self,sourcePath_list,targetPath_list):#done
|
||||||
|
#print("BTN Man: MoveAtoB")
|
||||||
|
if (len(sourcePath_list) != len(targetPath_list)):
|
||||||
|
print("Error: Path Count mismatch")
|
||||||
|
print("Source: {} | Target:{} ".format(len(sourcePath_list),len(targetPath_list)))
|
||||||
|
print("Source: {} ".format(sourcePath_list))
|
||||||
|
print("Target: {} ".format(targetPath_list))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
for index in range(0,len(sourcePath_list)) :
|
||||||
|
sourcePath = sourcePath_list[index]
|
||||||
|
targetPath = targetPath_list[index]
|
||||||
|
shutil.move(sourcePath,targetPath)
|
||||||
|
except PermissionError:
|
||||||
|
print("PermissionError. Try function in admin-role!")
|
||||||
|
except Exception as e:
|
||||||
|
try:
|
||||||
|
print("Error: ()".format(e.what()))
|
||||||
|
except:
|
||||||
|
print("Unknown Error.")
|
||||||
|
|
||||||
|
def delete(self,targetPath):#done
|
||||||
|
if os.path.isdir(targetPath):
|
||||||
|
shutil.rmtree(targetPath,ignore_errors=True)
|
||||||
|
else:
|
||||||
|
if os.path.isfile(targetPath):
|
||||||
|
os.remove(targetPath)
|
||||||
|
else:
|
||||||
|
#dürfte nie auftreten
|
||||||
|
print("Error Delete: File doesn't exist anymore")
|
||||||
|
|
||||||
|
|
||||||
|
##DXM Bragi - Hauptprogramm
|
||||||
|
class DXM_Bragi(qtw.QMainWindow):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args,**kwargs)
|
||||||
|
|
||||||
|
self.main_window = Ui_dxmb()
|
||||||
|
self.main_window.setupUi(self)
|
||||||
|
|
||||||
|
self.btn_man = BTN_MANAGER()
|
||||||
|
|
||||||
|
self.homePath = os.getenv('USERPROFILE')
|
||||||
|
self.curr_filePath = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
self.prepare_songbook_tab()
|
||||||
|
self.prepare_learnTaste_tab()
|
||||||
|
self.prepare_searchSongs_tab()
|
||||||
|
|
||||||
|
self.ytVidODict = OrderedDict()
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
## SongBook Tab (Filesystem für Song-Verwaltung Tab)
|
||||||
|
def prepare_songbook_tab(self):#semi done (nur noch connecten zu Analyse)
|
||||||
|
#Vorbereiten aller Felder und Funktionen für Songbook
|
||||||
|
|
||||||
|
#Source TreeView (Links)
|
||||||
|
#Default Source Path "Eigene Musik" von User (Wenn nicht da dann Home Order selbst)
|
||||||
|
|
||||||
|
self.sourcePath = self.homePath
|
||||||
|
if (self.homePath !=None):
|
||||||
|
musicPath = os.path.join(self.homePath,'Music')
|
||||||
|
if (os.path.isdir(musicPath)):
|
||||||
|
self.sourcePath = musicPath
|
||||||
|
|
||||||
|
self.model_source = qtw.QFileSystemModel()
|
||||||
|
self.model_source.setRootPath(self.sourcePath)
|
||||||
|
|
||||||
|
self.setTreeView("Source",self.main_window.treeView_source,self.model_source,self.sourcePath)
|
||||||
|
|
||||||
|
#Target TreeView(Rechts)
|
||||||
|
#Default Target Path in aktuellem File Ordner (Defualt in Audio-Library)
|
||||||
|
#Wenn Ordner noch nicht exisitert -> Erstellen
|
||||||
|
targetPath = os.path.join(self.curr_filePath, "Audio Library")
|
||||||
|
|
||||||
|
if (not os.path.isdir(targetPath)):
|
||||||
|
os.makedirs(targetPath)
|
||||||
|
|
||||||
|
self.model_target = qtw.QFileSystemModel()
|
||||||
|
self.model_target.setRootPath(targetPath)
|
||||||
|
|
||||||
|
self.setTreeView("Target",self.main_window.treeView_target,self.model_target,targetPath)
|
||||||
|
|
||||||
|
#Funktionsbuttons connecten
|
||||||
|
#SourceTree(links)
|
||||||
|
self.main_window.btn_copyToTarget.clicked.connect(self.copy_file_sourceToTarget)
|
||||||
|
self.main_window.btn_copyAllToTarget.clicked.connect(self.copy_fileAll_sourceToTarget)
|
||||||
|
self.main_window.btn_moveToTarget.clicked.connect(self.move_file_sourceToTarget)
|
||||||
|
self.main_window.btn_moveAllToTarget.clicked.connect(self.move_fileAll_sourceToTarget)
|
||||||
|
self.main_window.btn_deleteSourceItem.clicked.connect(self.delete_file_source)
|
||||||
|
self.main_window.btn_makeDirSource.clicked.connect(self.make_dir_source)
|
||||||
|
self.main_window.btn_analyseSource.clicked.connect(self.analyse_file_source)
|
||||||
|
self.main_window.toolButton_source.clicked.connect(self.setNewRootPath_source)
|
||||||
|
|
||||||
|
#TargetTree(rechts)
|
||||||
|
self.main_window.btn_copyToSource.clicked.connect(self.copy_file_targetToSource)
|
||||||
|
self.main_window.btn_copyAllToSource.clicked.connect(self.copy_fileAll_targetToSource)
|
||||||
|
self.main_window.btn_moveToSource.clicked.connect(self.move_file_targetToSource)
|
||||||
|
self.main_window.btn_moveAllToSource.clicked.connect(self.move_fileAll_targetToSource)
|
||||||
|
self.main_window.btn_deleteTargetItem.clicked.connect(self.delete_file_target)
|
||||||
|
self.main_window.btn_makeDirTarget.clicked.connect(self.make_dir_target)
|
||||||
|
self.main_window.btn_analyseTarget.clicked.connect(self.analyse_file_target)
|
||||||
|
self.main_window.toolButton_target.clicked.connect(self.setNewRootPath_target)
|
||||||
|
|
||||||
|
####
|
||||||
|
## Context Menü Funktionen
|
||||||
|
####
|
||||||
|
|
||||||
|
def context_Menu_source(self):#semi-done(Add new menus)
|
||||||
|
menu = qtw.QMenu()
|
||||||
|
open = menu.addAction("Open")
|
||||||
|
open.triggered.connect(self.open_file_source)
|
||||||
|
|
||||||
|
cursor = qtg.QCursor()
|
||||||
|
menu.exec_(cursor.pos())
|
||||||
|
|
||||||
|
def context_Menu_target(self):#semi-done(Add new menus)
|
||||||
|
menu = qtw.QMenu()
|
||||||
|
open = menu.addAction("Open")
|
||||||
|
open.triggered.connect(self.open_file_target)
|
||||||
|
|
||||||
|
cursor = qtg.QCursor()
|
||||||
|
menu.exec_(cursor.pos())
|
||||||
|
|
||||||
|
def open_file_source(self):#done
|
||||||
|
index = self.tree_source.currentIndex()
|
||||||
|
tree_file_path = self.model_source.filePath(index)
|
||||||
|
os.startfile(tree_file_path)
|
||||||
|
|
||||||
|
def open_file_target(self):#done
|
||||||
|
index = self.tree_target.currentIndex()
|
||||||
|
tree_file_path = self.model_target.filePath(index)
|
||||||
|
os.startfile(tree_file_path)
|
||||||
|
|
||||||
|
####
|
||||||
|
## Source TreeView Funktionen
|
||||||
|
####
|
||||||
|
def copy_file_sourceToTarget(self):#done
|
||||||
|
self.copy_file_AToB(self.tree_source,self.model_source,self.tree_target,self.model_target,self.main_window.lineEdit_target)
|
||||||
|
|
||||||
|
def copy_fileAll_sourceToTarget(self):#done
|
||||||
|
index_source = self.tree_source.currentIndex()
|
||||||
|
if (os.path.isdir(self.model_source.filePath(index_source))):
|
||||||
|
self.copy_file_AToB(self.tree_source,self.model_source,self.tree_target,self.model_target,self.main_window.lineEdit_target)
|
||||||
|
else:
|
||||||
|
self.copy_file_AToB(self.tree_source,self.model_source,self.tree_target,self.model_target,self.main_window.lineEdit_target,True)
|
||||||
|
|
||||||
|
def move_file_sourceToTarget(self):#dome
|
||||||
|
self.move_file_AToB(self.tree_source,self.model_source,self.tree_target,self.model_target,self.main_window.lineEdit_target)
|
||||||
|
|
||||||
|
def move_fileAll_sourceToTarget(self):#done
|
||||||
|
self.move_file_AToB(self.tree_source,self.model_source,self.tree_target,self.model_target,self.main_window.lineEdit_target,True)
|
||||||
|
|
||||||
|
def delete_file_source(self):#done
|
||||||
|
self.delete_file_inTree(self.tree_source,self.model_source)
|
||||||
|
|
||||||
|
def make_dir_source(self):#done
|
||||||
|
self.readDirName(self.tree_source,self.model_source,self.main_window.lineEdit_source)
|
||||||
|
|
||||||
|
def setNewRootPath_source(self):#done
|
||||||
|
self.setNewRootPath("Source",self.main_window.lineEdit_source.text())
|
||||||
|
|
||||||
|
def analyse_file_source(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
####
|
||||||
|
## Target TreeView Funktionen
|
||||||
|
####
|
||||||
|
def copy_file_targetToSource(self):#done
|
||||||
|
self.copy_file_AToB(self.tree_target,self.model_target,self.tree_source,self.model_source,self.main_window.lineEdit_source)
|
||||||
|
|
||||||
|
def copy_fileAll_targetToSource(self):#done
|
||||||
|
index_target = self.tree_target.currentIndex()
|
||||||
|
if (os.path.isdir(self.model_target.filePath(index_target))):
|
||||||
|
self.copy_file_AToB(self.tree_target,self.model_target,self.tree_source,self.model_source,self.main_window.lineEdit_source)
|
||||||
|
else:
|
||||||
|
self.copy_file_AToB(self.tree_target,self.model_target,self.tree_source,self.model_source,self.main_window.lineEdit_source,True)
|
||||||
|
|
||||||
|
def move_file_targetToSource(self):#done
|
||||||
|
self.move_file_AToB(self.tree_target,self.model_target,self.tree_source,self.model_source,self.main_window.lineEdit_source)
|
||||||
|
|
||||||
|
def move_fileAll_targetToSource(self):#done
|
||||||
|
self.move_file_AToB(self.tree_target,self.model_target,self.tree_source,self.model_source,self.main_window.lineEdit_source,True)
|
||||||
|
|
||||||
|
def delete_file_target(self):#done
|
||||||
|
self.delete_file_inTree(self.tree_target,self.model_target)
|
||||||
|
|
||||||
|
def make_dir_target(self):#done
|
||||||
|
self.readDirName(self.tree_target,self.model_target,self.main_window.lineEdit_target)
|
||||||
|
|
||||||
|
def setNewRootPath_target(self):#done
|
||||||
|
self.setNewRootPath("Target",self.main_window.lineEdit_target.text())
|
||||||
|
|
||||||
|
def analyse_file_target(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
####
|
||||||
|
## Allgemeine ToolFunktionen
|
||||||
|
####
|
||||||
|
def setTreeView(self,profile ,treeView,model,newPath):
|
||||||
|
#TODO iwann herausfinden wie columns über HeaderData in FileSystemModel geändert werden können
|
||||||
|
#Vermutlich irgendwie über subclasse bilden
|
||||||
|
if( profile == "Source"):
|
||||||
|
self.tree_source = treeView
|
||||||
|
self.tree_source.setModel(model)
|
||||||
|
self.tree_source.setAlternatingRowColors(True)
|
||||||
|
model.directoryLoaded.connect(self.tree_source.expandAll)
|
||||||
|
self.tree_source.setRootIndex(model.index(newPath))
|
||||||
|
self.tree_source.setSortingEnabled(True)
|
||||||
|
self.tree_source.setContextMenuPolicy(qtc.Qt.CustomContextMenu)
|
||||||
|
self.tree_source.customContextMenuRequested.connect(self.context_Menu_source)
|
||||||
|
self.tree_source.setColumnWidth(0,175)
|
||||||
|
self.tree_source.setColumnWidth(1,50)
|
||||||
|
self.main_window.lineEdit_source.setText(newPath)
|
||||||
|
elif (profile == "Target"):
|
||||||
|
self.tree_target = treeView
|
||||||
|
self.tree_target.setModel(model)
|
||||||
|
self.tree_target.setAlternatingRowColors(True)
|
||||||
|
model.directoryLoaded.connect(self.tree_target.expandAll)
|
||||||
|
self.tree_target.setRootIndex(model.index(newPath))
|
||||||
|
self.tree_target.setSortingEnabled(True)
|
||||||
|
self.tree_target.setContextMenuPolicy(qtc.Qt.CustomContextMenu)
|
||||||
|
self.tree_target.customContextMenuRequested.connect(self.context_Menu_target)
|
||||||
|
self.tree_target.setColumnWidth(0,175)
|
||||||
|
self.tree_target.setColumnWidth(1,50)
|
||||||
|
self.main_window.lineEdit_target.setText(newPath)
|
||||||
|
else:
|
||||||
|
print("Error: Unknown TreeView")
|
||||||
|
|
||||||
|
def copy_file_AToB(self,treeSource,modelSource,treeTarget,modelTarget,lineEditTarget,copyFromParentFolder=False):#done
|
||||||
|
#Note Regeln: Wenn kein source index gewählt-> kein einzel Copy
|
||||||
|
index_source = treeSource.currentIndex()
|
||||||
|
if (modelSource.filePath(index_source) ==''):
|
||||||
|
#Fehler :Ohne selektion kein einzel copy
|
||||||
|
print("Error: Kein einzel copy ohne Selektion")
|
||||||
|
return
|
||||||
|
|
||||||
|
treeSource_filePath = list()
|
||||||
|
if (copyFromParentFolder):
|
||||||
|
treeSource_filePath.append(os.path.dirname(modelSource.filePath(index_source)))
|
||||||
|
else:
|
||||||
|
treeSource_filePath.append(modelSource.filePath(index_source))
|
||||||
|
|
||||||
|
index_target = treeTarget.currentIndex()
|
||||||
|
treeTarget_filePath = list()
|
||||||
|
if (modelTarget.filePath(index_target) ==''):
|
||||||
|
treeTarget_filePath.append(lineEditTarget.text())
|
||||||
|
|
||||||
|
if (os.path.isdir(modelTarget.filePath(index_target))):
|
||||||
|
treeTarget_dirName = modelTarget.filePath(index_target)
|
||||||
|
else:
|
||||||
|
treeTarget_dirName = os.path.dirname(modelTarget.filePath(index_target))
|
||||||
|
if (copyFromParentFolder):
|
||||||
|
target_dirName = os.path.dirname(modelTarget.filePath(index_target))
|
||||||
|
treeTarget_filePath.append(target_dirName)
|
||||||
|
else:
|
||||||
|
treeSource_fileName = modelSource.fileName(index_source)
|
||||||
|
treeTarget_filePath.append(os.path.join(treeTarget_dirName,treeSource_fileName))
|
||||||
|
|
||||||
|
#Auführen des Copy-Befehls von BTN-Man
|
||||||
|
self.btn_man.copyAtoB(treeSource_filePath,treeTarget_filePath)
|
||||||
|
|
||||||
|
def move_file_AToB(self,treeSource,modelSource,treeTarget,modelTarget,lineEditTarget,moveAllInFolder=False):#done
|
||||||
|
#Note Regeln: Wenn kein Index gewählt-> Nichts bewegen(Keine Aktion)
|
||||||
|
#Wenn Ordner als Index (Außer Root Ordner) -> Kompletten order + Inhalt zu Ziel Bewegen
|
||||||
|
#Wenn MoveAll auf File als Index -> alle Elemente des Parent ordners OHNE Ordner selbst bewegen
|
||||||
|
#Wenn MoveAll auf Ordner als Index -> Kompletten ordner + Inhalt zu Ziel bewegen
|
||||||
|
|
||||||
|
index_source = treeSource.currentIndex()
|
||||||
|
if (modelSource.filePath(index_source) ==''):
|
||||||
|
#Fehler :Ohne selektion kein einzel copy
|
||||||
|
print("Error: Kein einzel move ohne Selektion")
|
||||||
|
return
|
||||||
|
|
||||||
|
treeSource_filePath = list()
|
||||||
|
treeSource_fileNames = list()
|
||||||
|
sourceIsDir = False
|
||||||
|
if (os.path.isdir(modelSource.filePath(index_source))):#Move/MoveAll auf Folder
|
||||||
|
sourceIsDir = True
|
||||||
|
#Wenn Index ein Folder ist dann ist moveAll Funktion = move Funktion
|
||||||
|
moveAllInFolder = False
|
||||||
|
treeSource_filePath.append(modelSource.filePath(index_source))
|
||||||
|
else:
|
||||||
|
if (moveAllInFolder):#MoveAll auf File
|
||||||
|
for file in os.listdir(os.path.dirname(modelSource.filePath(index_source))):
|
||||||
|
treeSource_filePath.append(os.path.join(os.path.dirname(modelSource.filePath(index_source)),file))
|
||||||
|
treeSource_fileNames.append(file)
|
||||||
|
else:#Move auf einzelnes File
|
||||||
|
treeSource_filePath.append(modelSource.filePath(index_source))
|
||||||
|
treeSource_fileName = modelSource.fileName(index_source)
|
||||||
|
|
||||||
|
index_target = treeTarget.currentIndex()
|
||||||
|
treeTarget_filePath = list()
|
||||||
|
treeTarget_dirName = str()
|
||||||
|
targetIsDir = False
|
||||||
|
if (modelTarget.filePath(index_target) ==''):
|
||||||
|
treeTarget_dirName = lineEditTarget.text()
|
||||||
|
#RootOrdner in LineEdit ist IMMER Folder
|
||||||
|
targetIsDir = True
|
||||||
|
else:
|
||||||
|
if (os.path.isdir(modelTarget.filePath(index_target))):
|
||||||
|
treeTarget_dirName = modelTarget.filePath(index_target)
|
||||||
|
targetIsDir = True
|
||||||
|
else:
|
||||||
|
treeTarget_dirName = os.path.dirname(modelTarget.filePath(index_target))
|
||||||
|
|
||||||
|
if(moveAllInFolder):#MoveAll auf File in Source -> Einzel-Move-Paths vorbereiten
|
||||||
|
for file in treeSource_fileNames:
|
||||||
|
treeTarget_filePath.append(os.path.join(treeTarget_dirName,file))
|
||||||
|
else:
|
||||||
|
if (sourceIsDir == True and targetIsDir == True):
|
||||||
|
treeTarget_filePath.append(modelTarget.filePath(index_target))
|
||||||
|
elif(sourceIsDir == True and targetIsDir == False):
|
||||||
|
treeTarget_filePath.append(treeTarget_dirName)
|
||||||
|
else:
|
||||||
|
treeTarget_filePath.append(os.path.join(treeTarget_dirName,treeSource_fileName))
|
||||||
|
|
||||||
|
#Ausführen BTN-Man Funktion
|
||||||
|
self.btn_man.moveAtoB(treeSource_filePath,treeTarget_filePath)
|
||||||
|
|
||||||
|
def delete_file_inTree(self,targetTree,targetModel):#done
|
||||||
|
#Note Regeln: Wenn kein Index gewählt -> Kein File Löschen (Keine Aktion; vllt Warn-Print)
|
||||||
|
#Wenn Ordner als Index (Außer Root Ordner) -> Kompletten order + Inhalt löschen
|
||||||
|
index_source = targetTree.currentIndex()
|
||||||
|
if (targetModel.filePath(index_source) ==''):
|
||||||
|
#Fehler :Ohne selektion kein einzel delete
|
||||||
|
print("Error: Kein einzel copy ohne Selektion")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ausführen BTN-Man Command
|
||||||
|
self.btn_man.delete(targetModel.filePath(index_source))
|
||||||
|
|
||||||
|
def readDirName(self,tree,model,lineEdit):#done
|
||||||
|
name, result = qtw.QInputDialog.getText(self, "Folder Name","Enter new folder name:")
|
||||||
|
if(result):
|
||||||
|
index_source = tree.currentIndex()
|
||||||
|
if (model.filePath(index_source) ==''):
|
||||||
|
#Kein Index gewählt-> LineEdit als Quell-Pfad
|
||||||
|
filePath = os.path.join(lineEdit.text(),name)
|
||||||
|
else:
|
||||||
|
if (os.path.isdir(model.filePath(index_source))):
|
||||||
|
filePath = os.path.join(model.filePath(index_source),name)
|
||||||
|
else:
|
||||||
|
dirName = os.path.dirname(model.filePath(index_source))
|
||||||
|
filePath = os.path.join(dirName,name)
|
||||||
|
os.makedirs(filePath)
|
||||||
|
else:
|
||||||
|
print("Error: Eingabe Abbruch")
|
||||||
|
|
||||||
|
def setNewRootPath(self,profile,currentPath):#done
|
||||||
|
dialog = qtw.QFileDialog(self)
|
||||||
|
dialog.setWindowTitle('Set Root Path for Tree')
|
||||||
|
dialog.setDirectory(currentPath)
|
||||||
|
dialog.setFileMode(qtw.QFileDialog.DirectoryOnly)
|
||||||
|
if dialog.exec_() == qtw.QDialog.Accepted:
|
||||||
|
file_full_path = str(dialog.selectedFiles()[0])
|
||||||
|
print(file_full_path)
|
||||||
|
if (profile == "Source"):
|
||||||
|
self.model_source = qtw.QFileSystemModel()
|
||||||
|
self.model_source.setRootPath(file_full_path)
|
||||||
|
self.setTreeView("Source",self.main_window.treeView_source,self.model_source,file_full_path)
|
||||||
|
elif(profile == "Target"):
|
||||||
|
self.model_target = qtw.QFileSystemModel()
|
||||||
|
self.model_target.setRootPath(file_full_path)
|
||||||
|
self.setTreeView("Target",self.main_window.treeView_target,self.model_target,file_full_path)
|
||||||
|
else:
|
||||||
|
print("Error: Unknown TreeView")
|
||||||
|
else:
|
||||||
|
print("Error: Abbruch SetNewRoot")
|
||||||
|
|
||||||
|
def analyse_file(self,filePah):
|
||||||
|
# Nutze ausgewähltes File für "Learn Taste Tab" und starte analyse
|
||||||
|
pass
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
## Learn Taste tab (MachineLearning Tab)
|
||||||
|
def prepare_learnTaste_tab(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
## Search Songs tab (Youtube-Downloader & ML-Prediction Tab)
|
||||||
|
def prepare_searchSongs_tab(self):
|
||||||
|
|
||||||
|
self.targetPath = os.path.join(self.curr_filePath, "Downloads")
|
||||||
|
if (not os.path.isdir(self.targetPath)):
|
||||||
|
os.makedirs(self.targetPath)
|
||||||
|
|
||||||
|
self.main_window.lineEdit_targetPath.setText(self.targetPath)
|
||||||
|
|
||||||
|
#Funktionsbuttons connecten
|
||||||
|
self.main_window.btn_insertUrl.clicked.connect(self.insertUrl)
|
||||||
|
self.main_window.toolBtn_targetPath.clicked.connect(self.setTargetPath)
|
||||||
|
self.main_window.toolBtn_addProfile.clicked.connect(self.addProfile)
|
||||||
|
self.main_window.toolBtn_removeProfile.clicked.connect(self.removeProfile)
|
||||||
|
|
||||||
|
|
||||||
|
def insertUrl(self):
|
||||||
|
self.main_window.insert_url_msg.setText("")
|
||||||
|
if (self.main_window.lineEdit_url.text() == ''):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
newUrl = self.main_window.lineEdit_url.text()
|
||||||
|
|
||||||
|
##Checken ob Link bereits als Objekt vorliegt (2mal laden der gleichen URL führt zu absturz)
|
||||||
|
if newUrl.strip() in self.ytVidODict:
|
||||||
|
self.main_window.insert_url_msg.setText("Error: URL allready loaded")
|
||||||
|
return
|
||||||
|
|
||||||
|
#Test URL: Rick Roll https://www.youtube.com/watch?v=o-YBDTqX_ZU
|
||||||
|
#Test URL2: BudS&TerH - Lala Remix: https://www.youtube.com/watch?v=lL7jwhWAU_k
|
||||||
|
#Test URL3: Nee Junge: https://www.youtube.com/watch?v=1uNHA3pcDmQ
|
||||||
|
|
||||||
|
item = QYTVidItem(self.main_window.scrollA)
|
||||||
|
returnCode = item.setData(newUrl)
|
||||||
|
#print("returnCode: ",returnCode )
|
||||||
|
if (returnCode == "OK"):
|
||||||
|
row = self.main_window.url_scroller_grid.count()
|
||||||
|
col = 0
|
||||||
|
self.main_window.url_scroller_grid.setRowStretch(row,0)
|
||||||
|
self.main_window.url_scroller_grid.addWidget(item,row,col,0,0)
|
||||||
|
#Setzen der externen Buttons
|
||||||
|
item.btn_remove.clicked.connect(partial(self.removeYTVid,newUrl))
|
||||||
|
item.btn_download.clicked.connect(partial(self.downloadYTVid,newUrl))
|
||||||
|
#Speichern in der OrderedDict:
|
||||||
|
self.ytVidODict[newUrl.strip()] = item
|
||||||
|
else:
|
||||||
|
self.main_window.insert_url_msg.setText(returnCode)
|
||||||
|
|
||||||
|
self.main_window.lineEdit_url.setText("")
|
||||||
|
|
||||||
|
|
||||||
|
def setTargetPath(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addProfile(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def removeProfile(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def downloadYTVid(self,url):
|
||||||
|
targetPath = self.main_window.lineEdit_targetPath.text()
|
||||||
|
print("Download nach {}".format(targetPath))
|
||||||
|
for vidItem in self.ytVidODict:
|
||||||
|
if vidItem == url.strip():
|
||||||
|
self.ytVidODict[vidItem].downloadItem(targetPath)
|
||||||
|
return
|
||||||
|
print("Error: ungültiges Item")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def removeYTVid(self,url):
|
||||||
|
#Rauswerfen aus der Scrollarea (nachrücken aller folgenden Items im Grid)
|
||||||
|
for vidItem in self.ytVidODict:
|
||||||
|
if vidItem == url.strip():
|
||||||
|
self.ytVidODict[vidItem].deleteLater()
|
||||||
|
self.ytVidODict.pop(url.strip())
|
||||||
|
break
|
||||||
|
|
||||||
|
#danach gridlayout neu aufbauen
|
||||||
|
for i in reversed(range(self.main_window.url_scroller_grid.count())):
|
||||||
|
widgetToRemove = self.main_window.url_scroller_grid.itemAt( i ).widget()
|
||||||
|
# remove it from the layout list
|
||||||
|
self.main_window.url_scroller_grid.removeWidget( widgetToRemove )
|
||||||
|
|
||||||
|
# gridlayout neu aufbauen
|
||||||
|
for vidItem in self.ytVidODict:
|
||||||
|
row = self.main_window.url_scroller_grid.count()
|
||||||
|
col = 0
|
||||||
|
self.main_window.url_scroller_grid.addWidget(self.ytVidODict[vidItem],row,col,1,1)
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
## ChangeSongsDetails Tab (ID3-Tag Editor für Songs Tab)
|
||||||
|
def changeSongDetails_tab(self):#to be implemented
|
||||||
|
#Auslesen und Manipulieren aller ID3 Tags eines Songs
|
||||||
|
pass
|
||||||
|
|
||||||
|
#############################################################################################
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = qtw.QApplication([])
|
||||||
|
|
||||||
|
##Set "DarkMode"
|
||||||
|
app.setStyle("Fusion")
|
||||||
|
# Now use a palette to switch to dark colors:
|
||||||
|
palette = qtg.QPalette()
|
||||||
|
palette.setColor(qtg.QPalette.Window, qtg.QColor(53, 53, 53))
|
||||||
|
palette.setColor(qtg.QPalette.WindowText, qtc.Qt.white)
|
||||||
|
palette.setColor(qtg.QPalette.Base, qtg.QColor(25, 25, 25))
|
||||||
|
palette.setColor(qtg.QPalette.AlternateBase, qtg.QColor(53, 53, 53))
|
||||||
|
palette.setColor(qtg.QPalette.ToolTipBase, qtc.Qt.black)
|
||||||
|
palette.setColor(qtg.QPalette.ToolTipText, qtc.Qt.white)
|
||||||
|
palette.setColor(qtg.QPalette.Text, qtc.Qt.white)
|
||||||
|
palette.setColor(qtg.QPalette.Button, qtg.QColor(53, 53, 53))
|
||||||
|
palette.setColor(qtg.QPalette.ButtonText, qtc.Qt.white)
|
||||||
|
palette.setColor(qtg.QPalette.BrightText, qtc.Qt.red)
|
||||||
|
palette.setColor(qtg.QPalette.Link, qtg.QColor(42, 130, 218))
|
||||||
|
palette.setColor(qtg.QPalette.Highlight, qtg.QColor(42, 130, 218))
|
||||||
|
palette.setColor(qtg.QPalette.HighlightedText, qtc.Qt.black)
|
||||||
|
app.setPalette(palette)
|
||||||
|
|
||||||
|
mwindow = DXM_Bragi()
|
||||||
|
mwindow.show()
|
||||||
|
|
||||||
|
##youtube test: https://www.youtube.com/watch?v=Lrj2Hq7xqQ8
|
||||||
|
#link = 'https://www.youtube.com/watch?v=Lrj2Hq7xqQ8'
|
||||||
|
#yt_vid = YouTube(link)
|
||||||
|
#filePath = os.path.join(os.path.dirname(os.path.abspath(__file__)),'TestYT')
|
||||||
|
|
||||||
|
##zeigt vorhandene stream items an (Verschiedene Versionen des links)
|
||||||
|
#for video in yt_video.streams:
|
||||||
|
# print(video)
|
||||||
|
|
||||||
|
##anzeigen Video daten
|
||||||
|
#print(yt_vid.title)
|
||||||
|
#print(yt_vid.thumbnail_url)
|
||||||
|
#print(yt_vid.streams.filter(only_audio=True))
|
||||||
|
|
||||||
|
##caption infos (Audio-Abschnitte[können auto generiert sein])
|
||||||
|
#print(yt_vid.captions)
|
||||||
|
#caption = yt_vid.captions.get_by_language_code('a.en')
|
||||||
|
#print(caption.xml_captions)
|
||||||
|
#print(caption.generate_srt_captions())
|
||||||
|
|
||||||
|
# herunter laden von audio in bester qualy
|
||||||
|
#yt_audioStream = yt_vid.streams.get_audio_only()
|
||||||
|
#print(yt_audioStream.title)
|
||||||
|
#yt_audioStream.download(filePath)
|
||||||
|
|
||||||
|
app.exec_()
|
@ -0,0 +1,556 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>dxmb</class>
|
||||||
|
<widget class="QMainWindow" name="dxmb">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>598</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>DXM Bragi</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>Datenverwaltung</string>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="data_tab">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Songbook</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="hor_layout_data_tab">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="vert_layout_source_tree">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="hor_layout_path_sourcce">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_source">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolButton_source">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="treeView_source"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="vert_layout_btn_range">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_seperator_upper">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="vert_layout_btn_target">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_copyToTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy ></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_copyAllToTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy All >></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_moveToTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>Move ></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_moveAllToTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>Move All >></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_deleteTargetItem">
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete ></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_analyseTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>Analyse ></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_makeDirTarget">
|
||||||
|
<property name="text">
|
||||||
|
<string>New Dir ></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_seperator_lower">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="vert_layout_btn_source">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_copyToSource">
|
||||||
|
<property name="text">
|
||||||
|
<string>< Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_copyAllToSource">
|
||||||
|
<property name="text">
|
||||||
|
<string><< Copy All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_moveToSource">
|
||||||
|
<property name="text">
|
||||||
|
<string>< Move</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_moveAllToSource">
|
||||||
|
<property name="text">
|
||||||
|
<string><< Move All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_deleteSourceItem">
|
||||||
|
<property name="text">
|
||||||
|
<string>< Delete</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_analyseSource">
|
||||||
|
<property name="text">
|
||||||
|
<string>< Analyse</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_makeDirSource">
|
||||||
|
<property name="text">
|
||||||
|
<string>< New Dir</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="vert_layout_target_tree">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="hor_layout_path_target">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_target">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Normal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolButton_target">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="treeView_target"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="ml_tab">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleDescription">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Learn Taste</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="loader_tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Search Songs</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="HL_Header">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="HL_InsertLink">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_url">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Insert new video or playlist link </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btn_insertUrl">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert Link</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="insert_url_msg">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollA">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAWContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>754</width>
|
||||||
|
<height>298</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="url_scroller_grid" columnstretch="0" columnminimumwidth="0">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupB_loaderDetails">
|
||||||
|
<property name="title">
|
||||||
|
<string>Configuration</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="HL_TargetPath">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_targetPath">
|
||||||
|
<property name="text">
|
||||||
|
<string>Target Path:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_targetPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolBtn_targetPath">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="HL_Profile">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolBtn_addProfile">
|
||||||
|
<property name="text">
|
||||||
|
<string>+</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolBtn_removeProfile">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox_profile">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="currentText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_autoPredictTaste">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto predict taste for profile</string>
|
||||||
|
</property>
|
||||||
|
<property name="tristate">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioBtn_video">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkBox_bestQual">
|
||||||
|
<property name="text">
|
||||||
|
<string>Prefer best quality</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioBtn_audioOnly">
|
||||||
|
<property name="text">
|
||||||
|
<string>Audio Only</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkBox_autoDownload">
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto-Download on Insert</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioBtn_bothFiles">
|
||||||
|
<property name="text">
|
||||||
|
<string>Both (2 Files)</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -0,0 +1,338 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\DXM_Bragi_Files\DXMB_main.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.9.2
|
||||||
|
#
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
class Ui_dxmb(object):
|
||||||
|
def setupUi(self, dxmb):
|
||||||
|
dxmb.setObjectName("dxmb")
|
||||||
|
dxmb.resize(800, 598)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(dxmb.sizePolicy().hasHeightForWidth())
|
||||||
|
dxmb.setSizePolicy(sizePolicy)
|
||||||
|
self.centralwidget = QtWidgets.QWidget(dxmb)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
|
||||||
|
self.centralwidget.setSizePolicy(sizePolicy)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
|
||||||
|
self.tabWidget.setSizePolicy(sizePolicy)
|
||||||
|
self.tabWidget.setMinimumSize(QtCore.QSize(0, 0))
|
||||||
|
self.tabWidget.setBaseSize(QtCore.QSize(0, 0))
|
||||||
|
self.tabWidget.setObjectName("tabWidget")
|
||||||
|
self.data_tab = QtWidgets.QWidget()
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.data_tab.sizePolicy().hasHeightForWidth())
|
||||||
|
self.data_tab.setSizePolicy(sizePolicy)
|
||||||
|
self.data_tab.setAccessibleName("")
|
||||||
|
self.data_tab.setObjectName("data_tab")
|
||||||
|
self.gridLayout_2 = QtWidgets.QGridLayout(self.data_tab)
|
||||||
|
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||||
|
self.hor_layout_data_tab = QtWidgets.QHBoxLayout()
|
||||||
|
self.hor_layout_data_tab.setObjectName("hor_layout_data_tab")
|
||||||
|
self.vert_layout_source_tree = QtWidgets.QVBoxLayout()
|
||||||
|
self.vert_layout_source_tree.setObjectName("vert_layout_source_tree")
|
||||||
|
self.hor_layout_path_sourcce = QtWidgets.QHBoxLayout()
|
||||||
|
self.hor_layout_path_sourcce.setObjectName("hor_layout_path_sourcce")
|
||||||
|
self.lineEdit_source = QtWidgets.QLineEdit(self.data_tab)
|
||||||
|
self.lineEdit_source.setEnabled(True)
|
||||||
|
self.lineEdit_source.setReadOnly(True)
|
||||||
|
self.lineEdit_source.setObjectName("lineEdit_source")
|
||||||
|
self.hor_layout_path_sourcce.addWidget(self.lineEdit_source)
|
||||||
|
self.toolButton_source = QtWidgets.QToolButton(self.data_tab)
|
||||||
|
self.toolButton_source.setObjectName("toolButton_source")
|
||||||
|
self.hor_layout_path_sourcce.addWidget(self.toolButton_source)
|
||||||
|
self.vert_layout_source_tree.addLayout(self.hor_layout_path_sourcce)
|
||||||
|
self.treeView_source = QtWidgets.QTreeView(self.data_tab)
|
||||||
|
self.treeView_source.setObjectName("treeView_source")
|
||||||
|
self.vert_layout_source_tree.addWidget(self.treeView_source)
|
||||||
|
self.hor_layout_data_tab.addLayout(self.vert_layout_source_tree)
|
||||||
|
self.vert_layout_btn_range = QtWidgets.QVBoxLayout()
|
||||||
|
self.vert_layout_btn_range.setObjectName("vert_layout_btn_range")
|
||||||
|
self.btn_seperator_upper = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_seperator_upper.setText("")
|
||||||
|
self.btn_seperator_upper.setFlat(True)
|
||||||
|
self.btn_seperator_upper.setObjectName("btn_seperator_upper")
|
||||||
|
self.vert_layout_btn_range.addWidget(self.btn_seperator_upper)
|
||||||
|
self.vert_layout_btn_target = QtWidgets.QVBoxLayout()
|
||||||
|
self.vert_layout_btn_target.setObjectName("vert_layout_btn_target")
|
||||||
|
self.btn_copyToTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_copyToTarget.setObjectName("btn_copyToTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_copyToTarget)
|
||||||
|
self.btn_copyAllToTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_copyAllToTarget.setObjectName("btn_copyAllToTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_copyAllToTarget)
|
||||||
|
self.btn_moveToTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_moveToTarget.setObjectName("btn_moveToTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_moveToTarget)
|
||||||
|
self.btn_moveAllToTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_moveAllToTarget.setObjectName("btn_moveAllToTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_moveAllToTarget)
|
||||||
|
self.btn_deleteTargetItem = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_deleteTargetItem.setObjectName("btn_deleteTargetItem")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_deleteTargetItem)
|
||||||
|
self.btn_analyseTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_analyseTarget.setObjectName("btn_analyseTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_analyseTarget)
|
||||||
|
self.btn_makeDirTarget = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_makeDirTarget.setObjectName("btn_makeDirTarget")
|
||||||
|
self.vert_layout_btn_target.addWidget(self.btn_makeDirTarget)
|
||||||
|
self.vert_layout_btn_range.addLayout(self.vert_layout_btn_target)
|
||||||
|
self.btn_seperator_lower = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_seperator_lower.setText("")
|
||||||
|
self.btn_seperator_lower.setFlat(True)
|
||||||
|
self.btn_seperator_lower.setObjectName("btn_seperator_lower")
|
||||||
|
self.vert_layout_btn_range.addWidget(self.btn_seperator_lower)
|
||||||
|
self.vert_layout_btn_source = QtWidgets.QVBoxLayout()
|
||||||
|
self.vert_layout_btn_source.setObjectName("vert_layout_btn_source")
|
||||||
|
self.btn_copyToSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_copyToSource.setObjectName("btn_copyToSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_copyToSource)
|
||||||
|
self.btn_copyAllToSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_copyAllToSource.setObjectName("btn_copyAllToSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_copyAllToSource)
|
||||||
|
self.btn_moveToSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_moveToSource.setObjectName("btn_moveToSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_moveToSource)
|
||||||
|
self.btn_moveAllToSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_moveAllToSource.setObjectName("btn_moveAllToSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_moveAllToSource)
|
||||||
|
self.btn_deleteSourceItem = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_deleteSourceItem.setObjectName("btn_deleteSourceItem")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_deleteSourceItem)
|
||||||
|
self.btn_analyseSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_analyseSource.setObjectName("btn_analyseSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_analyseSource)
|
||||||
|
self.btn_makeDirSource = QtWidgets.QPushButton(self.data_tab)
|
||||||
|
self.btn_makeDirSource.setObjectName("btn_makeDirSource")
|
||||||
|
self.vert_layout_btn_source.addWidget(self.btn_makeDirSource)
|
||||||
|
self.vert_layout_btn_range.addLayout(self.vert_layout_btn_source)
|
||||||
|
self.hor_layout_data_tab.addLayout(self.vert_layout_btn_range)
|
||||||
|
self.vert_layout_target_tree = QtWidgets.QVBoxLayout()
|
||||||
|
self.vert_layout_target_tree.setObjectName("vert_layout_target_tree")
|
||||||
|
self.hor_layout_path_target = QtWidgets.QHBoxLayout()
|
||||||
|
self.hor_layout_path_target.setObjectName("hor_layout_path_target")
|
||||||
|
self.lineEdit_target = QtWidgets.QLineEdit(self.data_tab)
|
||||||
|
self.lineEdit_target.setEnabled(True)
|
||||||
|
self.lineEdit_target.setEchoMode(QtWidgets.QLineEdit.Normal)
|
||||||
|
self.lineEdit_target.setReadOnly(True)
|
||||||
|
self.lineEdit_target.setObjectName("lineEdit_target")
|
||||||
|
self.hor_layout_path_target.addWidget(self.lineEdit_target)
|
||||||
|
self.toolButton_target = QtWidgets.QToolButton(self.data_tab)
|
||||||
|
self.toolButton_target.setObjectName("toolButton_target")
|
||||||
|
self.hor_layout_path_target.addWidget(self.toolButton_target)
|
||||||
|
self.vert_layout_target_tree.addLayout(self.hor_layout_path_target)
|
||||||
|
self.treeView_target = QtWidgets.QTreeView(self.data_tab)
|
||||||
|
self.treeView_target.setObjectName("treeView_target")
|
||||||
|
self.vert_layout_target_tree.addWidget(self.treeView_target)
|
||||||
|
self.hor_layout_data_tab.addLayout(self.vert_layout_target_tree)
|
||||||
|
self.gridLayout_2.addLayout(self.hor_layout_data_tab, 0, 0, 1, 1)
|
||||||
|
self.tabWidget.addTab(self.data_tab, "")
|
||||||
|
self.ml_tab = QtWidgets.QWidget()
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.ml_tab.sizePolicy().hasHeightForWidth())
|
||||||
|
self.ml_tab.setSizePolicy(sizePolicy)
|
||||||
|
self.ml_tab.setToolTip("")
|
||||||
|
self.ml_tab.setWhatsThis("")
|
||||||
|
self.ml_tab.setAccessibleName("")
|
||||||
|
self.ml_tab.setAccessibleDescription("")
|
||||||
|
self.ml_tab.setObjectName("ml_tab")
|
||||||
|
self.tabWidget.addTab(self.ml_tab, "")
|
||||||
|
self.loader_tab = QtWidgets.QWidget()
|
||||||
|
self.loader_tab.setObjectName("loader_tab")
|
||||||
|
self.gridLayout_4 = QtWidgets.QGridLayout(self.loader_tab)
|
||||||
|
self.gridLayout_4.setObjectName("gridLayout_4")
|
||||||
|
self.verticalLayout_4 = QtWidgets.QVBoxLayout()
|
||||||
|
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||||
|
self.HL_Header = QtWidgets.QVBoxLayout()
|
||||||
|
self.HL_Header.setObjectName("HL_Header")
|
||||||
|
self.HL_InsertLink = QtWidgets.QHBoxLayout()
|
||||||
|
self.HL_InsertLink.setObjectName("HL_InsertLink")
|
||||||
|
self.lineEdit_url = QtWidgets.QLineEdit(self.loader_tab)
|
||||||
|
self.lineEdit_url.setText("")
|
||||||
|
self.lineEdit_url.setObjectName("lineEdit_url")
|
||||||
|
self.HL_InsertLink.addWidget(self.lineEdit_url)
|
||||||
|
self.btn_insertUrl = QtWidgets.QPushButton(self.loader_tab)
|
||||||
|
self.btn_insertUrl.setObjectName("btn_insertUrl")
|
||||||
|
self.HL_InsertLink.addWidget(self.btn_insertUrl)
|
||||||
|
self.HL_Header.addLayout(self.HL_InsertLink)
|
||||||
|
self.insert_url_msg = QtWidgets.QLabel(self.loader_tab)
|
||||||
|
self.insert_url_msg.setEnabled(True)
|
||||||
|
self.insert_url_msg.setText("")
|
||||||
|
self.insert_url_msg.setScaledContents(False)
|
||||||
|
self.insert_url_msg.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
|
self.insert_url_msg.setWordWrap(True)
|
||||||
|
self.insert_url_msg.setObjectName("insert_url_msg")
|
||||||
|
self.HL_Header.addWidget(self.insert_url_msg)
|
||||||
|
self.verticalLayout_4.addLayout(self.HL_Header)
|
||||||
|
self.scrollA = QtWidgets.QScrollArea(self.loader_tab)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
sizePolicy.setHorizontalStretch(1)
|
||||||
|
sizePolicy.setVerticalStretch(1)
|
||||||
|
sizePolicy.setHeightForWidth(self.scrollA.sizePolicy().hasHeightForWidth())
|
||||||
|
self.scrollA.setSizePolicy(sizePolicy)
|
||||||
|
self.scrollA.setMaximumSize(QtCore.QSize(16777215, 16777215))
|
||||||
|
self.scrollA.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||||
|
self.scrollA.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||||
|
self.scrollA.setWidgetResizable(True)
|
||||||
|
self.scrollA.setObjectName("scrollA")
|
||||||
|
self.scrollAWContents = QtWidgets.QWidget()
|
||||||
|
self.scrollAWContents.setGeometry(QtCore.QRect(0, 0, 754, 298))
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.scrollAWContents.sizePolicy().hasHeightForWidth())
|
||||||
|
self.scrollAWContents.setSizePolicy(sizePolicy)
|
||||||
|
self.scrollAWContents.setMinimumSize(QtCore.QSize(0, 10))
|
||||||
|
self.scrollAWContents.setMaximumSize(QtCore.QSize(16777215, 16777215))
|
||||||
|
self.scrollAWContents.setBaseSize(QtCore.QSize(0, 10))
|
||||||
|
self.scrollAWContents.setObjectName("scrollAWContents")
|
||||||
|
self.url_scroller_grid = QtWidgets.QGridLayout(self.scrollAWContents)
|
||||||
|
self.url_scroller_grid.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
|
||||||
|
self.url_scroller_grid.setContentsMargins(-1, -1, 9, -1)
|
||||||
|
self.url_scroller_grid.setHorizontalSpacing(1)
|
||||||
|
self.url_scroller_grid.setObjectName("url_scroller_grid")
|
||||||
|
self.scrollA.setWidget(self.scrollAWContents)
|
||||||
|
self.verticalLayout_4.addWidget(self.scrollA)
|
||||||
|
self.groupB_loaderDetails = QtWidgets.QGroupBox(self.loader_tab)
|
||||||
|
self.groupB_loaderDetails.setFlat(False)
|
||||||
|
self.groupB_loaderDetails.setObjectName("groupB_loaderDetails")
|
||||||
|
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupB_loaderDetails)
|
||||||
|
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||||
|
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
||||||
|
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||||
|
self.HL_TargetPath = QtWidgets.QHBoxLayout()
|
||||||
|
self.HL_TargetPath.setObjectName("HL_TargetPath")
|
||||||
|
self.label_targetPath = QtWidgets.QLabel(self.groupB_loaderDetails)
|
||||||
|
self.label_targetPath.setObjectName("label_targetPath")
|
||||||
|
self.HL_TargetPath.addWidget(self.label_targetPath)
|
||||||
|
self.lineEdit_targetPath = QtWidgets.QLineEdit(self.groupB_loaderDetails)
|
||||||
|
self.lineEdit_targetPath.setObjectName("lineEdit_targetPath")
|
||||||
|
self.HL_TargetPath.addWidget(self.lineEdit_targetPath)
|
||||||
|
self.toolBtn_targetPath = QtWidgets.QToolButton(self.groupB_loaderDetails)
|
||||||
|
self.toolBtn_targetPath.setObjectName("toolBtn_targetPath")
|
||||||
|
self.HL_TargetPath.addWidget(self.toolBtn_targetPath)
|
||||||
|
self.verticalLayout_2.addLayout(self.HL_TargetPath)
|
||||||
|
self.HL_Profile = QtWidgets.QHBoxLayout()
|
||||||
|
self.HL_Profile.setObjectName("HL_Profile")
|
||||||
|
self.toolBtn_addProfile = QtWidgets.QToolButton(self.groupB_loaderDetails)
|
||||||
|
self.toolBtn_addProfile.setObjectName("toolBtn_addProfile")
|
||||||
|
self.HL_Profile.addWidget(self.toolBtn_addProfile)
|
||||||
|
self.toolBtn_removeProfile = QtWidgets.QToolButton(self.groupB_loaderDetails)
|
||||||
|
self.toolBtn_removeProfile.setEnabled(False)
|
||||||
|
self.toolBtn_removeProfile.setObjectName("toolBtn_removeProfile")
|
||||||
|
self.HL_Profile.addWidget(self.toolBtn_removeProfile)
|
||||||
|
self.comboBox_profile = QtWidgets.QComboBox(self.groupB_loaderDetails)
|
||||||
|
self.comboBox_profile.setEnabled(True)
|
||||||
|
self.comboBox_profile.setEditable(False)
|
||||||
|
self.comboBox_profile.setCurrentText("")
|
||||||
|
self.comboBox_profile.setMinimumContentsLength(0)
|
||||||
|
self.comboBox_profile.setObjectName("comboBox_profile")
|
||||||
|
self.HL_Profile.addWidget(self.comboBox_profile)
|
||||||
|
self.checkBox_autoPredictTaste = QtWidgets.QCheckBox(self.groupB_loaderDetails)
|
||||||
|
self.checkBox_autoPredictTaste.setEnabled(False)
|
||||||
|
self.checkBox_autoPredictTaste.setTristate(False)
|
||||||
|
self.checkBox_autoPredictTaste.setObjectName("checkBox_autoPredictTaste")
|
||||||
|
self.HL_Profile.addWidget(self.checkBox_autoPredictTaste)
|
||||||
|
self.verticalLayout_2.addLayout(self.HL_Profile)
|
||||||
|
self.gridLayout = QtWidgets.QGridLayout()
|
||||||
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.radioBtn_video = QtWidgets.QRadioButton(self.groupB_loaderDetails)
|
||||||
|
self.radioBtn_video.setChecked(True)
|
||||||
|
self.radioBtn_video.setObjectName("radioBtn_video")
|
||||||
|
self.gridLayout.addWidget(self.radioBtn_video, 0, 0, 1, 1)
|
||||||
|
self.checkBox_bestQual = QtWidgets.QCheckBox(self.groupB_loaderDetails)
|
||||||
|
self.checkBox_bestQual.setObjectName("checkBox_bestQual")
|
||||||
|
self.gridLayout.addWidget(self.checkBox_bestQual, 0, 1, 1, 1)
|
||||||
|
self.radioBtn_audioOnly = QtWidgets.QRadioButton(self.groupB_loaderDetails)
|
||||||
|
self.radioBtn_audioOnly.setObjectName("radioBtn_audioOnly")
|
||||||
|
self.gridLayout.addWidget(self.radioBtn_audioOnly, 1, 0, 1, 1)
|
||||||
|
self.checkBox_autoDownload = QtWidgets.QCheckBox(self.groupB_loaderDetails)
|
||||||
|
self.checkBox_autoDownload.setObjectName("checkBox_autoDownload")
|
||||||
|
self.gridLayout.addWidget(self.checkBox_autoDownload, 1, 1, 1, 1)
|
||||||
|
self.radioBtn_bothFiles = QtWidgets.QRadioButton(self.groupB_loaderDetails)
|
||||||
|
self.radioBtn_bothFiles.setChecked(False)
|
||||||
|
self.radioBtn_bothFiles.setObjectName("radioBtn_bothFiles")
|
||||||
|
self.gridLayout.addWidget(self.radioBtn_bothFiles, 2, 0, 1, 1)
|
||||||
|
self.verticalLayout_2.addLayout(self.gridLayout)
|
||||||
|
self.verticalLayout_3.addLayout(self.verticalLayout_2)
|
||||||
|
self.verticalLayout_4.addWidget(self.groupB_loaderDetails)
|
||||||
|
self.gridLayout_4.addLayout(self.verticalLayout_4, 0, 0, 1, 1)
|
||||||
|
self.tabWidget.addTab(self.loader_tab, "")
|
||||||
|
self.verticalLayout.addWidget(self.tabWidget)
|
||||||
|
dxmb.setCentralWidget(self.centralwidget)
|
||||||
|
self.statusbar = QtWidgets.QStatusBar(dxmb)
|
||||||
|
self.statusbar.setObjectName("statusbar")
|
||||||
|
dxmb.setStatusBar(self.statusbar)
|
||||||
|
|
||||||
|
self.retranslateUi(dxmb)
|
||||||
|
self.tabWidget.setCurrentIndex(2)
|
||||||
|
self.comboBox_profile.setCurrentIndex(-1)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(dxmb)
|
||||||
|
|
||||||
|
def retranslateUi(self, dxmb):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
dxmb.setWindowTitle(_translate("dxmb", "DXM Bragi"))
|
||||||
|
self.tabWidget.setAccessibleName(_translate("dxmb", "Datenverwaltung"))
|
||||||
|
self.toolButton_source.setText(_translate("dxmb", "..."))
|
||||||
|
self.btn_copyToTarget.setText(_translate("dxmb", "Copy >"))
|
||||||
|
self.btn_copyAllToTarget.setText(_translate("dxmb", "Copy All >>"))
|
||||||
|
self.btn_moveToTarget.setText(_translate("dxmb", "Move >"))
|
||||||
|
self.btn_moveAllToTarget.setText(_translate("dxmb", "Move All >>"))
|
||||||
|
self.btn_deleteTargetItem.setText(_translate("dxmb", "Delete >"))
|
||||||
|
self.btn_analyseTarget.setText(_translate("dxmb", "Analyse >"))
|
||||||
|
self.btn_makeDirTarget.setText(_translate("dxmb", "New Dir >"))
|
||||||
|
self.btn_copyToSource.setText(_translate("dxmb", "< Copy"))
|
||||||
|
self.btn_copyAllToSource.setText(_translate("dxmb", "<< Copy All"))
|
||||||
|
self.btn_moveToSource.setText(_translate("dxmb", "< Move"))
|
||||||
|
self.btn_moveAllToSource.setText(_translate("dxmb", "<< Move All"))
|
||||||
|
self.btn_deleteSourceItem.setText(_translate("dxmb", "< Delete"))
|
||||||
|
self.btn_analyseSource.setText(_translate("dxmb", "< Analyse"))
|
||||||
|
self.btn_makeDirSource.setText(_translate("dxmb", "< New Dir"))
|
||||||
|
self.toolButton_target.setText(_translate("dxmb", "..."))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.data_tab), _translate("dxmb", "Songbook"))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.ml_tab), _translate("dxmb", "Learn Taste"))
|
||||||
|
self.lineEdit_url.setPlaceholderText(_translate("dxmb", "Insert new video or playlist link "))
|
||||||
|
self.btn_insertUrl.setText(_translate("dxmb", "Insert Link"))
|
||||||
|
self.groupB_loaderDetails.setTitle(_translate("dxmb", "Configuration"))
|
||||||
|
self.label_targetPath.setText(_translate("dxmb", "Target Path:"))
|
||||||
|
self.toolBtn_targetPath.setText(_translate("dxmb", "..."))
|
||||||
|
self.toolBtn_addProfile.setText(_translate("dxmb", "+"))
|
||||||
|
self.toolBtn_removeProfile.setText(_translate("dxmb", "-"))
|
||||||
|
self.checkBox_autoPredictTaste.setText(_translate("dxmb", "Auto predict taste for profile"))
|
||||||
|
self.radioBtn_video.setText(_translate("dxmb", "Video"))
|
||||||
|
self.checkBox_bestQual.setText(_translate("dxmb", "Prefer best quality"))
|
||||||
|
self.radioBtn_audioOnly.setText(_translate("dxmb", "Audio Only"))
|
||||||
|
self.checkBox_autoDownload.setText(_translate("dxmb", "Auto-Download on Insert"))
|
||||||
|
self.radioBtn_bothFiles.setText(_translate("dxmb", "Both (2 Files)"))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.loader_tab), _translate("dxmb", "Search Songs"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
dxmb = QtWidgets.QMainWindow()
|
||||||
|
ui = Ui_dxmb()
|
||||||
|
ui.setupUi(dxmb)
|
||||||
|
dxmb.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
|
@ -0,0 +1,329 @@
|
|||||||
|
from PyQt5 import QtWidgets as qtw
|
||||||
|
from PyQt5 import QtGui as qtg
|
||||||
|
from PyQt5 import QtCore as qtc
|
||||||
|
|
||||||
|
from pytube import Playlist, YouTube, exceptions
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from range_slider import RangeSlider
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QApplication, QGridLayout, QWidget, QListWidget, QVBoxLayout, QLabel, QPushButton, QListWidgetItem, \
|
||||||
|
QHBoxLayout
|
||||||
|
|
||||||
|
#Todo ersetzen durch QNetworkRequest and QNetworkReply -> soll besser und sicherer funktionieren da urllib blocken kann
|
||||||
|
from urllib.request import urlopen
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
import resources
|
||||||
|
|
||||||
|
class QYTVidItem(qtw.QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(QYTVidItem, self).__init__(parent)
|
||||||
|
|
||||||
|
sizePolicy = qtw.QSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Minimum)
|
||||||
|
#self.sizePolicy = qtw.QSizePolicy(qtw.QSizePolicy.Maximum, qtw.QSizePolicy.Maximum)
|
||||||
|
#sizePolicy.setHeightForWidth(messageformForm.sizePolicy().hasHeightForWidth())
|
||||||
|
#self.sizePolicy.setHorizontalStretch(True)
|
||||||
|
self.setSizePolicy(sizePolicy)
|
||||||
|
|
||||||
|
self.vid_layout = qtw.QHBoxLayout()
|
||||||
|
self.vidDetailLayout = qtw.QVBoxLayout()
|
||||||
|
self.vidHeaderLayout = qtw.QHBoxLayout()
|
||||||
|
self.vidSpecsLayout = qtw.QHBoxLayout()
|
||||||
|
self.vidStartEndLayout = qtw.QHBoxLayout()
|
||||||
|
self.buttonLayout = qtw.QHBoxLayout()
|
||||||
|
self.buttonLayout.setSizeConstraint(qtw.QLayout.SizeConstraint.SetMinimumSize)
|
||||||
|
|
||||||
|
self.title = ""
|
||||||
|
self.url = ""
|
||||||
|
|
||||||
|
self.currentFormat = 'mp4'
|
||||||
|
self.currentRes = 'best'
|
||||||
|
|
||||||
|
self.defaultThumbPix = qtg.QPixmap(":/assets/bagi_default.png")
|
||||||
|
|
||||||
|
#debug -> Rosa hintergrund für Size test
|
||||||
|
pal = qtg.QPalette()
|
||||||
|
pal.setColor(qtg.QPalette.Background, qtg.QColor(218, 94, 242))
|
||||||
|
self.setPalette(pal)
|
||||||
|
self.setAutoFillBackground(True)
|
||||||
|
|
||||||
|
def setData(self,purl):
|
||||||
|
print("setdata for: {}".format(purl))
|
||||||
|
self.url = purl.strip()
|
||||||
|
|
||||||
|
errTxt = self.checkLink(purl)
|
||||||
|
if (errTxt != "OK"):
|
||||||
|
return errTxt
|
||||||
|
|
||||||
|
# Youtube vid infos laden
|
||||||
|
#debug
|
||||||
|
#purl = "https://www.youtube.com/watch?v=Lrj2Hq7xqQ8"
|
||||||
|
self.yt_vid = YouTube(url=purl)
|
||||||
|
|
||||||
|
print("Url Found. Title:{}".format(self.yt_vid.title))
|
||||||
|
self.title = self.yt_vid.title
|
||||||
|
|
||||||
|
#url = "https://i.ytimg.com/vi/Lrj2Hq7xqQ8/maxresdefault.jpg"
|
||||||
|
thumbNail_url = self.yt_vid.thumbnail_url
|
||||||
|
thumbPixmap = qtg.QPixmap()
|
||||||
|
try: #wenn thumbnail url ungültig oder nicht geladen werden konnte -> default setzen
|
||||||
|
request = urllib.request.Request(thumbNail_url)
|
||||||
|
response = urllib.request.urlopen(request)
|
||||||
|
data = response.read()
|
||||||
|
thumbPixmap.loadFromData(data)
|
||||||
|
except Exception:
|
||||||
|
self.thumbPixmap.load(":/assets/bragi_default.png")
|
||||||
|
|
||||||
|
##Linke Seite:
|
||||||
|
# Thumbnail des Videos (oder default wenn keins vorhanden)
|
||||||
|
icoLabel = qtw.QLabel()
|
||||||
|
icoLabel.setPixmap(thumbPixmap.scaled(150,150,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.vid_layout.addWidget(icoLabel)
|
||||||
|
|
||||||
|
##Rechte Seite des Widgets
|
||||||
|
# Oberste Reihe:
|
||||||
|
# Titel, btn_edit, btn_remove
|
||||||
|
self.title_edit = qtw.QLineEdit(self.yt_vid.title)
|
||||||
|
self.title_edit.setReadOnly(True)
|
||||||
|
self.vidHeaderLayout.addWidget(self.title_edit)
|
||||||
|
|
||||||
|
#self.vidHeaderLayout.addStretch()
|
||||||
|
|
||||||
|
pixmap_edit = qtg.QPixmap(":/assets/edit.svg")
|
||||||
|
icon_edit = qtg.QIcon(pixmap_edit.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_edit = qtw.QToolButton()
|
||||||
|
self.btn_edit.setIcon(icon_edit)
|
||||||
|
self.btn_edit.clicked.connect(self.toggleTitleEditable)
|
||||||
|
self.vidHeaderLayout.addWidget(self.btn_edit)
|
||||||
|
|
||||||
|
pixmap_remove = qtg.QPixmap(":/assets/cancel2.svg")
|
||||||
|
icon_remove = qtg.QIcon(pixmap_remove.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_remove = qtw.QToolButton()
|
||||||
|
self.btn_remove.setIcon(icon_remove)
|
||||||
|
self.vidHeaderLayout.addWidget(self.btn_remove)
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.vidHeaderLayout)
|
||||||
|
|
||||||
|
# Mittlere Reihe:
|
||||||
|
# Video Specs
|
||||||
|
dur_time = self.yt_vid.length
|
||||||
|
duration = qtw.QLabel("Duration: {} sec".format(dur_time))
|
||||||
|
self.vidSpecsLayout.addWidget(duration)
|
||||||
|
|
||||||
|
#self.vidSpecsLayout.addStretch()
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.vidSpecsLayout)
|
||||||
|
|
||||||
|
# vorletze reihe:
|
||||||
|
# Start/Ende Marker
|
||||||
|
self.vidStartEndLayout.setContentsMargins(5,0,5,0)
|
||||||
|
self.vidStartEndLayout.setSpacing(10);
|
||||||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft)
|
||||||
|
|
||||||
|
slider = RangeSlider(qtc.Qt.Horizontal)
|
||||||
|
slider.setMinimumHeight(10)
|
||||||
|
slider.setMaximumWidth(200)
|
||||||
|
slider.setMinimum(0)
|
||||||
|
slider.setMaximum(dur_time)
|
||||||
|
slider.setLow(0)
|
||||||
|
slider.setHigh(dur_time)
|
||||||
|
slider.setTickPosition(qtw.QSlider.TicksBelow)
|
||||||
|
slider.sliderMoved.connect(self.updateSliderVal)
|
||||||
|
#QtCore.QObject.connect(slider, QtCore.SIGNAL('sliderMoved(int)'), echo)
|
||||||
|
slider.show()
|
||||||
|
slider.raise_()
|
||||||
|
self.vidStartEndLayout.addWidget(slider)
|
||||||
|
|
||||||
|
#self.vidStartEndLayout.addStretch()
|
||||||
|
|
||||||
|
vid_start_txt = qtw.QLabel("start at(sec):")
|
||||||
|
vid_start_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(vid_start_txt)
|
||||||
|
|
||||||
|
lowVal = slider.low()
|
||||||
|
self.vid_start = qtw.QLabel(str(lowVal))
|
||||||
|
self.vid_start.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(self.vid_start)
|
||||||
|
|
||||||
|
vid_end_txt = qtw.QLabel("end at(sec):")
|
||||||
|
vid_end_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(vid_end_txt)
|
||||||
|
|
||||||
|
highVal = slider.high()
|
||||||
|
self.vid_end = qtw.QLabel(str(highVal))
|
||||||
|
|
||||||
|
self.vidStartEndLayout.addWidget(self.vid_end)
|
||||||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidDetailLayout.addItem(self.vidStartEndLayout)
|
||||||
|
|
||||||
|
# Unterste Reihe:
|
||||||
|
# Combobox für Streamauswahl +
|
||||||
|
# Video spezifische Buttons (ordentliche pics)
|
||||||
|
#self.buttonLayout.setContentsMargins(5,0,5,0)
|
||||||
|
self.buttonLayout.setSpacing(10);
|
||||||
|
self.buttonLayout.setAlignment(qtc.Qt.AlignLeft)
|
||||||
|
|
||||||
|
self.format_combo = qtw.QComboBox()
|
||||||
|
self.format_combo.addItem('mp4(Video)')
|
||||||
|
self.format_combo.addItem('mp3(Audio)')
|
||||||
|
self.format_combo.setCurrentIndex(0)
|
||||||
|
self.buttonLayout.addWidget(self.format_combo)
|
||||||
|
|
||||||
|
self.resolution_combo = qtw.QComboBox()
|
||||||
|
#print(self.yt_vid.streams[0].itag)
|
||||||
|
for stream in self.yt_vid.streams:
|
||||||
|
print("{}\n".format(stream))
|
||||||
|
#self.resolution_combo.addItem(stream.value)
|
||||||
|
|
||||||
|
self.buttonLayout.addWidget(self.resolution_combo)
|
||||||
|
|
||||||
|
#self.buttonLayout.addStretch()
|
||||||
|
|
||||||
|
pixmap_play = qtg.QPixmap(":/assets/play2.svg")
|
||||||
|
icon_play = qtg.QIcon()
|
||||||
|
icon_play.addPixmap(pixmap_play.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
btn_play = qtw.QToolButton()
|
||||||
|
#btn_play.setPixmap(pixmap_play.scaled(25,25,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
btn_play.setIcon(icon_play)
|
||||||
|
btn_play.clicked.connect(self.playItem)
|
||||||
|
self.buttonLayout.addWidget(btn_play)
|
||||||
|
|
||||||
|
pixmap_stop = qtg.QPixmap(":/assets/stop2.svg")
|
||||||
|
icon_stop = qtg.QIcon()
|
||||||
|
icon_stop.addPixmap(pixmap_stop.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
btn_stop = qtw.QToolButton()
|
||||||
|
#btn_stop.setPixmap(pixmap_stop.scaled(25,25,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
btn_stop.setIcon(icon_stop)
|
||||||
|
btn_play.clicked.connect(self.stopItem)
|
||||||
|
self.buttonLayout.addWidget(btn_stop)
|
||||||
|
|
||||||
|
pixmap_download = qtg.QPixmap(":/assets/download.svg")
|
||||||
|
icon_download = qtg.QIcon()
|
||||||
|
icon_download.addPixmap(pixmap_download.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_download = qtw.QToolButton()
|
||||||
|
#btn_download.setPixmap(pixmap_download.scaled(25,25,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_download.setIcon(icon_download)
|
||||||
|
#self.btn_download.clicked.connect(self.downloadItem)
|
||||||
|
self.buttonLayout.addWidget(self.btn_download)
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.buttonLayout)
|
||||||
|
|
||||||
|
#Layouts zusammenfügen und setzen
|
||||||
|
self.vid_layout.addItem(self.vidDetailLayout)
|
||||||
|
#self.vid_layout.setSizeConstraint()
|
||||||
|
self.setLayout(self.vid_layout)
|
||||||
|
|
||||||
|
return errTxt
|
||||||
|
|
||||||
|
def toggleTitleEditable(self):
|
||||||
|
if self.title_edit.isReadOnly():
|
||||||
|
self.title_edit.setReadOnly(False)
|
||||||
|
self.title_edit.selectAll()
|
||||||
|
self.btn_download.setEnabled(False)
|
||||||
|
pixmap_edit = qtg.QPixmap(":/assets/check.svg")
|
||||||
|
icon_edit = qtg.QIcon(pixmap_edit.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_edit.setIcon(icon_edit)
|
||||||
|
else:
|
||||||
|
self.title_edit.deselect()
|
||||||
|
self.title_edit.setReadOnly(True)
|
||||||
|
self.btn_download.setEnabled(True)
|
||||||
|
pixmap_edit = qtg.QPixmap(":/assets/edit.svg")
|
||||||
|
icon_edit = qtg.QIcon(pixmap_edit.scaled(50,50,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.btn_edit.setIcon(icon_edit)
|
||||||
|
|
||||||
|
|
||||||
|
def toggleFormatResolution(self):
|
||||||
|
if self.currentFormat == 'mp4':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def updateSliderVal(self,low_value, high_value):
|
||||||
|
self.vid_start.setText(str(low_value))
|
||||||
|
self.vid_end.setText(str(high_value))
|
||||||
|
|
||||||
|
def playItem(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stopItem(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def downloadItem(self,path):
|
||||||
|
#self.yt_vid.streams.get_by_itag(251).download(path)
|
||||||
|
# download the file
|
||||||
|
|
||||||
|
out_file = self.yt_vid.streams.get_highest_resolution().download(output_path=path)
|
||||||
|
|
||||||
|
# save the file
|
||||||
|
base, ext = os.path.splitext(out_file)
|
||||||
|
print("base:{}".format(base))
|
||||||
|
new_file = base + '.mp4'
|
||||||
|
print("new:{}".format(new_file))
|
||||||
|
os.rename(out_file, new_file)
|
||||||
|
|
||||||
|
print("Download Triggered")
|
||||||
|
|
||||||
|
def checkLink(self,url):#done
|
||||||
|
try:
|
||||||
|
yttest = YouTube(url)
|
||||||
|
yttest.check_availability()
|
||||||
|
return "OK"
|
||||||
|
except exceptions.RegexMatchError:
|
||||||
|
errTxt = "Video Link invalid({}). Link is no valid url.".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
except exceptions.MembersOnly:
|
||||||
|
errTxt = "Video Link invalid({}). Only available to Members of that group.".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
except exceptions.RecordingUnavailable:
|
||||||
|
errTxt = "Video Link invalid({}). Live-Stream not available.".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
except exceptions.VideoRegionBlocked:
|
||||||
|
errTxt = "Video Link invalid({}). Not available in your region.".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
except exceptions.VideoPrivate:
|
||||||
|
errTxt = "Video Link invalid({}). Video is set to private.".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
except exceptions.VideoUnavailable:
|
||||||
|
errTxt = "Video Link invalid({}).".format(url)
|
||||||
|
print(errTxt)
|
||||||
|
return errTxt
|
||||||
|
else:
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': #Zum testen des Widget-Designs
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
window = QWidget()
|
||||||
|
|
||||||
|
title = QLabel("Demo for widgets in a QListWidget")
|
||||||
|
|
||||||
|
scrollA = qtw.QScrollArea()
|
||||||
|
scrollLayout = QGridLayout()
|
||||||
|
|
||||||
|
item_1 =QYTVidItem()
|
||||||
|
|
||||||
|
item_2 =QYTVidItem()
|
||||||
|
item_3 =QYTVidItem()
|
||||||
|
|
||||||
|
scrollLayout.addWidget(item_1,scrollLayout.count(),0)
|
||||||
|
item_1.setData("https://www.youtube.com/watch?v=Lrj2Hq7xqQ8")
|
||||||
|
scrollLayout.addWidget(item_2,scrollLayout.count(),0)
|
||||||
|
item_2.setData("https://www.youtube.com/watch?v=lL7jwhWAU_k")
|
||||||
|
#scrollLayout.addWidget(item_3)
|
||||||
|
|
||||||
|
scrollA.setLayout(scrollLayout)
|
||||||
|
|
||||||
|
window_layout = QVBoxLayout(window)
|
||||||
|
window_layout.addWidget(title)
|
||||||
|
window_layout.addWidget(scrollA)
|
||||||
|
window.setLayout(window_layout)
|
||||||
|
|
||||||
|
window.show()
|
||||||
|
|
||||||
|
sys.exit(app.exec_())
|
@ -0,0 +1,13 @@
|
|||||||
|
Wenn neues hinzukommt:
|
||||||
|
1) neues PNG (oder anderes Format das unterstützt ist [jpg ist es nicht])
|
||||||
|
in den Hauptordner zur .qrc Datei packen
|
||||||
|
2) in der ".qrc"-XML Datei die neuen Resources mit deren dateinamen eintragen (evtl alias wählen)
|
||||||
|
3) folgenden Befehl ausführen:
|
||||||
|
pyrcc5 "F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\DXM_Bragi_Files\resources.qrc" -o "F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\DXM_Bragi_Files\resources.py"
|
||||||
|
-> Lässt resourcecompile (rcc5) über alle im selben ordner befindlichen resources laufen
|
||||||
|
und erzeugt einen byte-array aller bilddaten
|
||||||
|
4) im programm, dass die resources nutzen soll prüfen ob resources.py importiert wird
|
||||||
|
5) im Programm immer wenn die resource genutzt werden soll statt pfad zur resource folgendes eintippen:
|
||||||
|
":/prefixAusResources/nameDerFileOderAlias"
|
||||||
|
|
||||||
|
Fertig: Resources sind in relativen pfad zur .qrc datei gebacken und können überall bequem aufgerufen werden
|
After Width: | Height: | Size: 540 KiB |
After Width: | Height: | Size: 298 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><path d="M962.6,962.6c-36.5,36.5-95.7,36.5-132.2,0L500,632.2L169.6,962.6c-36.5,36.5-95.7,36.5-132.2,0c-36.5-36.5-36.5-95.7,0-132.2L367.8,500L37.4,169.6c-36.5-36.5-36.5-95.7,0-132.2s95.7-36.5,132.2,0L500,367.8L830.4,37.4c36.5-36.5,95.7-36.5,132.2,0c36.5,36.5,36.5,95.7,0,132.2L632.2,500l330.4,330.4C999.1,866.9,999.1,926.1,962.6,962.6z"/></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 832 B |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><g><g><path d="M500,10C229.4,10,10,229.4,10,500c0,270.6,219.4,490,490,490c270.6,0,490-219.4,490-490C990,229.4,770.6,10,500,10z M600.8,500l178.5,178.5L678.5,779.3L500,600.8L321.5,779.3L220.7,678.5L399.2,500L220.7,321.5l100.8-100.9L500,399.2l178.5-178.5l100.8,100.8L600.8,500z"/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 885 B |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><g><g><path d="M827.9,540.7c-2.4-1.2-4.7-1.8-7.1-1.8c-5.1,0-9.6,2-13.5,5.9l-37.7,37.7c-3.5,3.5-5.3,7.9-5.3,13v149.7c0,25.9-9.2,48.1-27.7,66.6c-18.5,18.5-40.7,27.7-66.6,27.7H179.7c-25.9,0-48.1-9.2-66.6-27.7c-18.5-18.5-27.7-40.7-27.7-66.6V254.8c0-25.9,9.2-48.1,27.7-66.6c18.5-18.5,40.7-27.7,66.6-27.7H670c8.6,0,17.5,1.2,26.5,3.5c2.4,0.8,4.1,1.2,5.3,1.2c5.1,0,9.6-2,13.6-5.9l28.9-28.9c4.7-4.7,6.5-10.4,5.3-17.1c-1.2-6.3-4.7-10.8-10.6-13.6c-21.2-9.8-44.2-14.7-68.9-14.7H179.7c-46.8,0-86.7,16.6-119.9,49.8C26.6,168.1,10,208.1,10,254.9v490.3c0,46.7,16.6,86.7,49.8,119.9c33.2,33.2,73.2,49.8,119.9,49.8H670c46.7,0,86.7-16.6,119.9-49.8c33.2-33.2,49.8-73.2,49.8-119.9V557.7C839.7,549.5,835.8,543.8,827.9,540.7z"/><path d="M975.9,202.4L911,137.6c-9.4-9.4-20.6-14.1-33.6-14.1c-13,0-24.2,4.7-33.6,14.1L462.6,518.8l-155-155c-9.4-9.4-20.6-14.1-33.6-14.1c-13,0-24.2,4.7-33.6,14.1l-64.8,64.8c-9.4,9.4-14.1,20.6-14.1,33.6c0,13,4.7,24.2,14.1,33.6L429,749.3c9.4,9.4,20.6,14.1,33.6,14.1c13,0,24.2-4.7,33.6-14.1l479.7-479.7c9.4-9.4,14.1-20.6,14.1-33.6C990,223,985.3,211.8,975.9,202.4z"/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><g><g id="c23_download"><path d="M843.1,298.5H695.4v68.8h147.7c40.4,0,73.3,22.3,73.3,49.7v450c0,27.4-32.9,49.6-73.3,49.6H157c-40.5,0-73.5-22.2-73.5-49.6V417c0-27.4,32.9-49.7,73.5-49.7h147.5v-68.8H157c-81.3,0-147,44.4-147,99.3V886c0,54.8,65.7,99.2,147,99.2h686c81.1,0,146.9-44.4,146.9-99.2V397.7C990,342.9,924.3,298.5,843.1,298.5z"/><polygon points="355.9,519.2 215.5,519.2 503.5,861.2 784.5,510.7 644,510.7 644,275.3 644,209.4 644,14.8 355.9,14.8 355.9,209.4 355.9,275.3 "/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><g><path d="M967.4,181.1L818.9,32.6C803.7,17.5,783.9,10,764.1,10c-19.9,0-39.6,7.5-54.7,22.6L525.8,216.3H61.6c-28.5,0-51.6,23.1-51.6,51.6v670.5c0,28.5,23.1,51.6,51.6,51.6h670.5c28.5,0,51.6-23.1,51.6-51.6V474.2l183.7-183.7c15.1-15.1,22.6-34.9,22.6-54.7S982.5,196.3,967.4,181.1L967.4,181.1z M448.4,663.6l-112-112L661,227l112,112L448.4,663.6L448.4,663.6z M316.3,594.5l90.6,89.1l-87.4-3.1L316.3,594.5z M680.5,886.8H113.2V319.5h309.5l-164,164c-15.1,15.1-24.7,41.9-32.4,66.5c-8.3,25.8-9.9,54.5-9.9,75.8v157.9h157.9c21.4,0,57.1-5.2,81-15c23.9-9.8,46.2-17.9,61.3-33l164-158.3L680.5,886.8L680.5,886.8z M809.5,302.6l-112-112l66.7-66.7l112,112L809.5,302.6z"/></g></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><path d="M962.5,265.5l-99.4,99.4l-232-232l99.4-99.4c36.6-36.6,96-36.6,132.6,0l99.4,99.4C999.2,169.5,999.2,228.9,962.5,265.5z M763.7,464.3l-232-232l49.7-49.7l232,232L763.7,464.3z M318.1,895.6c-63.8,23.9-180.7,67.7-256.7,96.3c-14.4,5.7-68.7,2.8-45.9-50.5c25.7-74.3,63.6-183.9,85.3-246.5c15.8-44.1,21.9-55.7,53.7-85.3C247.2,517,482,282.1,482,282.1l232,232c0,0-220.6,229.4-311.8,324.3C372.5,872.3,359.5,880.3,318.1,895.6z"/></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 915 B |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><path d="M500,10C229.4,10,10,229.4,10,500c0,270.6,219.4,490,490,490s490-219.4,490-490C990,229.4,770.6,10,500,10L500,10z M725.3,525L410.5,711c-3.6,2.1-7.6,3.2-11.6,3.2c-4,0-8-1-11.6-3.2c-7.2-4.3-11.6-12.1-11.6-20.6V318.2c0-8.5,4.4-16.4,11.6-20.6c7.2-4.3,16.1-4.3,23.3,0l314.8,186.1c7.2,4.3,11.6,12.1,11.6,20.6C736.9,512.8,732.5,520.7,725.3,525L725.3,525z"/></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 851 B |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><path d="M108,990c-17.9,0-35.8-4.9-51.5-14.6C27.6,957.5,10,926,10,892V108c0-34,17.6-65.6,46.5-83.4C72.2,15,90.1,10,108,10c14.9,0,30.1,3.4,43.8,10.3l784,392C969,428.9,990,462.9,990,500s-21,71.1-54.2,87.7l-784,392C138.1,986.6,122.9,990,108,990z"/></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 740 B |
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource prefix='assets'>
|
||||||
|
<file>bagi_default.png</file>
|
||||||
|
<file>bragi_harp.png</file>
|
||||||
|
<file>cancelX.svg</file>
|
||||||
|
<file>cancel2.svg</file>
|
||||||
|
<file>download.svg</file>
|
||||||
|
<file>play.svg</file>
|
||||||
|
<file>play2.svg</file>
|
||||||
|
<file>stop.svg</file>
|
||||||
|
<file>stop2.svg</file>
|
||||||
|
<file>edit.svg</file>
|
||||||
|
<file>edit2.svg</file>
|
||||||
|
<file>check.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><g><path d="M500,10C229.4,10,10,229.4,10,500c0,270.6,219.4,490,490,490c270.6,0,490-219.4,490-490C990,229.4,770.6,10,500,10z M683.8,622.5c0,33.8-27.4,61.3-61.3,61.3h-245c-33.8,0-61.3-27.4-61.3-61.3v-245c0-33.8,27.4-61.3,61.3-61.3h245c33.8,0,61.3,27.4,61.3,61.3V622.5z"/></g></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 768 B |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||||
|
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||||
|
<g><path d="M885,10H115C57,10,10,57,10,115v770c0,58,47,105,105,105h770c58,0,105-47,105-105V115C990,57,943,10,885,10z"/></g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 611 B |
@ -0,0 +1,231 @@
|
|||||||
|
from PyQt5 import QtWidgets as qtw
|
||||||
|
from PyQt5 import QtGui as qtg
|
||||||
|
from PyQt5 import QtCore as qtc
|
||||||
|
|
||||||
|
from pytube import YouTube
|
||||||
|
from urllib.request import urlopen
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QApplication, QGridLayout, QVBoxLayout, QLabel
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(388, 255)
|
||||||
|
self.centralwidget = qtw.QWidget(MainWindow)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
self.widget = qtw.QWidget(self.centralwidget)
|
||||||
|
self.widget.setGeometry(qtc.QRect(20, 10, 361, 241))
|
||||||
|
self.widget.setObjectName("widget")
|
||||||
|
self.gridLayout = qtw.QGridLayout(self.centralwidget)
|
||||||
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.verticalLayout = qtw.QVBoxLayout(self.widget)
|
||||||
|
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.horizontalLayout = qtw.QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.lineEdit_url = qtw.QLineEdit(self.widget)
|
||||||
|
self.lineEdit_url.setObjectName("lineEdit_url")
|
||||||
|
self.horizontalLayout.addWidget(self.lineEdit_url)
|
||||||
|
self.insertUrl = qtw.QPushButton(self.widget)
|
||||||
|
self.insertUrl.setObjectName("insertUrl")
|
||||||
|
self.horizontalLayout.addWidget(self.insertUrl)
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
self.scrollA = qtw.QScrollArea(self.widget)
|
||||||
|
self.scrollA.setWidgetResizable(True)
|
||||||
|
self.scrollA.setObjectName("scrollA")
|
||||||
|
self.scrollAreaWidgetContents = qtw.QWidget()
|
||||||
|
self.scrollAreaWidgetContents.setGeometry(qtc.QRect(0, 0, 357, 206))
|
||||||
|
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||||
|
self.gridLayout_scroller = qtw.QGridLayout(self.scrollAreaWidgetContents)
|
||||||
|
self.gridLayout_scroller.setObjectName("gridLayout_scroller")
|
||||||
|
self.scrollA.setWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.verticalLayout.addWidget(self.scrollA)
|
||||||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
qtc.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
_translate = qtc.QCoreApplication.translate
|
||||||
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
||||||
|
self.insertUrl.setText(_translate("MainWindow", "PushButton"))
|
||||||
|
|
||||||
|
class QYTVidItem(qtw.QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(QYTVidItem, self).__init__(parent)
|
||||||
|
|
||||||
|
self.vid_layout = qtw.QHBoxLayout()
|
||||||
|
self.vidDetailLayout = qtw.QVBoxLayout()
|
||||||
|
self.vidHeaderLayout = qtw.QHBoxLayout()
|
||||||
|
self.vidSpecsLayout = qtw.QHBoxLayout()
|
||||||
|
self.vidStartEndLayout = qtw.QHBoxLayout()
|
||||||
|
self.buttonLayout = qtw.QHBoxLayout()
|
||||||
|
|
||||||
|
self.title = ""
|
||||||
|
self.url = ""
|
||||||
|
|
||||||
|
def setData(self,purl):
|
||||||
|
self.url = purl.strip()
|
||||||
|
|
||||||
|
errTxt = "OK"
|
||||||
|
|
||||||
|
# load Youtube vid infos
|
||||||
|
yt_vid = YouTube(url=purl)
|
||||||
|
|
||||||
|
self.title = yt_vid.title
|
||||||
|
|
||||||
|
##left Side:
|
||||||
|
# Thumbnail of video (or default if no thumb is found)
|
||||||
|
thumbNail_url = yt_vid.thumbnail_url
|
||||||
|
thumbPixmap = qtg.QPixmap()
|
||||||
|
try:
|
||||||
|
request = urllib.request.Request(thumbNail_url)
|
||||||
|
response = urllib.request.urlopen(request)
|
||||||
|
data = response.read()
|
||||||
|
thumbPixmap.loadFromData(data)
|
||||||
|
|
||||||
|
icoLabel = qtw.QLabel()
|
||||||
|
icoLabel.setPixmap(thumbPixmap.scaled(150,150,aspectRatioMode=qtc.Qt.KeepAspectRatio))
|
||||||
|
self.vid_layout.addWidget(icoLabel)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
##right side
|
||||||
|
# most upper row:
|
||||||
|
# title
|
||||||
|
title = qtw.QLabel(yt_vid.title)
|
||||||
|
self.vidHeaderLayout.addWidget(title)
|
||||||
|
|
||||||
|
self.btn_remove = qtw.QToolButton()
|
||||||
|
self.vidHeaderLayout.addWidget(self.btn_remove)
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.vidHeaderLayout)
|
||||||
|
|
||||||
|
# Mid row:
|
||||||
|
# Video Specs
|
||||||
|
dur_time = yt_vid.length
|
||||||
|
duration = qtw.QLabel("Duration: {} sec".format(dur_time))
|
||||||
|
self.vidSpecsLayout.addWidget(duration)
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.vidSpecsLayout)
|
||||||
|
|
||||||
|
# mid lower row:
|
||||||
|
# Start/End Marker
|
||||||
|
self.vidStartEndLayout.setContentsMargins(5,0,5,0)
|
||||||
|
self.vidStartEndLayout.setSpacing(10);
|
||||||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft)
|
||||||
|
|
||||||
|
vid_start_txt = qtw.QLabel("start at(sec):")
|
||||||
|
vid_start_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(vid_start_txt)
|
||||||
|
|
||||||
|
lowVal = 0
|
||||||
|
self.vid_start = qtw.QLabel(str(lowVal))
|
||||||
|
self.vid_start.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(self.vid_start)
|
||||||
|
|
||||||
|
vid_end_txt = qtw.QLabel("end at(sec):")
|
||||||
|
vid_end_txt.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidStartEndLayout.addWidget(vid_end_txt)
|
||||||
|
|
||||||
|
highVal = 99
|
||||||
|
self.vid_end = qtw.QLabel(str(highVal))
|
||||||
|
|
||||||
|
self.vidStartEndLayout.addWidget(self.vid_end)
|
||||||
|
self.vidStartEndLayout.setAlignment(qtc.Qt.AlignLeft|qtc.Qt.AlignVCenter)
|
||||||
|
self.vidDetailLayout.addItem(self.vidStartEndLayout)
|
||||||
|
|
||||||
|
# lower row:
|
||||||
|
# Video specific Buttons (picograms)
|
||||||
|
self.buttonLayout.setSpacing(10);
|
||||||
|
self.buttonLayout.setAlignment(qtc.Qt.AlignLeft)
|
||||||
|
|
||||||
|
btn_play = qtw.QToolButton()
|
||||||
|
self.buttonLayout.addWidget(btn_play)
|
||||||
|
|
||||||
|
btn_stop = qtw.QToolButton()
|
||||||
|
self.buttonLayout.addWidget(btn_stop)
|
||||||
|
|
||||||
|
btn_download = qtw.QToolButton()
|
||||||
|
self.buttonLayout.addWidget(btn_download)
|
||||||
|
|
||||||
|
self.vidDetailLayout.addItem(self.buttonLayout)
|
||||||
|
|
||||||
|
#assamble Layouts and activate it
|
||||||
|
self.vid_layout.addItem(self.vidDetailLayout)
|
||||||
|
self.setLayout(self.vid_layout)
|
||||||
|
|
||||||
|
return errTxt
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(qtw.QMainWindow):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args,**kwargs)
|
||||||
|
|
||||||
|
self.main_window = Ui_MainWindow()
|
||||||
|
self.main_window.setupUi(self)
|
||||||
|
|
||||||
|
self.ytVidODict = OrderedDict()
|
||||||
|
|
||||||
|
self.main_window.insertUrl.clicked.connect(self.insertUrl)
|
||||||
|
|
||||||
|
def insertUrl(self):
|
||||||
|
|
||||||
|
if (self.main_window.lineEdit_url.text() == ''):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
newUrl = self.main_window.lineEdit_url.text()
|
||||||
|
|
||||||
|
if newUrl.strip() in self.ytVidODict:
|
||||||
|
return
|
||||||
|
|
||||||
|
#Test URL: Rick Roll https://www.youtube.com/watch?v=Lrj2Hq7xqQ8
|
||||||
|
#Test URL2: BudS&TerH - Lala Remix: https://www.youtube.com/watch?v=lL7jwhWAU_k
|
||||||
|
|
||||||
|
item = QYTVidItem(self.main_window.scrollA)
|
||||||
|
returnCode = item.setData(newUrl)
|
||||||
|
if (returnCode == "OK"):
|
||||||
|
row = self.main_window.gridLayout_scroller.count()
|
||||||
|
col = 0
|
||||||
|
self.main_window.gridLayout_scroller.addWidget(item,row,col,1,1)
|
||||||
|
|
||||||
|
#save in OrderedDict:
|
||||||
|
item.btn_remove.clicked.connect(partial(self.removeYTVid,newUrl))
|
||||||
|
self.ytVidODict[newUrl.strip()] = item
|
||||||
|
else:
|
||||||
|
self.main_window.insert_url_msg.setText(returnCode)
|
||||||
|
|
||||||
|
self.main_window.lineEdit_url.setText("")
|
||||||
|
|
||||||
|
def removeYTVid(self,url):
|
||||||
|
#pop from ordered dict
|
||||||
|
for vidItem in self.ytVidODict:
|
||||||
|
if vidItem == url.strip():
|
||||||
|
self.ytVidODict.pop(url.strip())
|
||||||
|
break
|
||||||
|
|
||||||
|
#clear gridlayout from remaining children
|
||||||
|
for i in reversed(range(self.main_window.gridLayout_scroller.count())):
|
||||||
|
widgetToRemove = self.main_window.gridLayout_scroller.itemAt( i ).widget()
|
||||||
|
self.main_window.gridLayout_scroller.removeWidget( widgetToRemove )
|
||||||
|
|
||||||
|
#repopulate gridlayout
|
||||||
|
for vidItem in self.ytVidODict:
|
||||||
|
row = self.main_window.gridLayout_scroller.count()
|
||||||
|
col = 0
|
||||||
|
self.main_window.gridLayout_scroller.addWidget(self.ytVidODict[vidItem],row,col,1,1)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
window = MainWindow()
|
||||||
|
|
||||||
|
window.show()
|
||||||
|
|
||||||
|
sys.exit(app.exec_())
|
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>414</width>
|
||||||
|
<height>290</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_url"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="insertUrl">
|
||||||
|
<property name="text">
|
||||||
|
<string>PushButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollA">
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>392</width>
|
||||||
|
<height>237</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_scroller"/>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -0,0 +1,60 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'F:\Festplatte\Alex\Dev\Code\Projekte\[py] MachineLearning\DXM_Bragi_Files\example.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.9.2
|
||||||
|
#
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(414, 290)
|
||||||
|
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
|
||||||
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.lineEdit_url = QtWidgets.QLineEdit(self.centralwidget)
|
||||||
|
self.lineEdit_url.setObjectName("lineEdit_url")
|
||||||
|
self.horizontalLayout.addWidget(self.lineEdit_url)
|
||||||
|
self.insertUrl = QtWidgets.QPushButton(self.centralwidget)
|
||||||
|
self.insertUrl.setObjectName("insertUrl")
|
||||||
|
self.horizontalLayout.addWidget(self.insertUrl)
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
self.scrollA = QtWidgets.QScrollArea(self.centralwidget)
|
||||||
|
self.scrollA.setWidgetResizable(True)
|
||||||
|
self.scrollA.setObjectName("scrollA")
|
||||||
|
self.scrollAreaWidgetContents = QtWidgets.QWidget()
|
||||||
|
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 392, 237))
|
||||||
|
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||||
|
self.gridLayout_scroller = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
|
||||||
|
self.gridLayout_scroller.setObjectName("gridLayout_scroller")
|
||||||
|
self.scrollA.setWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.verticalLayout.addWidget(self.scrollA)
|
||||||
|
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
|
||||||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
||||||
|
self.insertUrl.setText(_translate("MainWindow", "PushButton"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
MainWindow = QtWidgets.QMainWindow()
|
||||||
|
ui = Ui_MainWindow()
|
||||||
|
ui.setupUi(MainWindow)
|
||||||
|
MainWindow.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
|
@ -0,0 +1,242 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys, os
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
# Originated from
|
||||||
|
# https://www.mail-archive.com/pyqt@riverbankcomputing.com/msg22889.html
|
||||||
|
# Modification refered from
|
||||||
|
# https://gist.github.com/Riateche/27e36977f7d5ea72cf4f
|
||||||
|
# https://github.com/Qt-Widgets/range_slider_for_Qt5_and_PyQt5
|
||||||
|
|
||||||
|
class RangeSlider(QtWidgets.QSlider):
|
||||||
|
sliderMoved = QtCore.pyqtSignal(int, int)
|
||||||
|
|
||||||
|
""" A slider for ranges.
|
||||||
|
|
||||||
|
This class provides a dual-slider for ranges, where there is a defined
|
||||||
|
maximum and minimum, as is a normal slider, but instead of having a
|
||||||
|
single slider value, there are 2 slider values.
|
||||||
|
|
||||||
|
This class emits the same signals as the QSlider base class, with the
|
||||||
|
exception of valueChanged
|
||||||
|
"""
|
||||||
|
def __init__(self, *args):
|
||||||
|
super(RangeSlider, self).__init__(*args)
|
||||||
|
|
||||||
|
self._low = self.minimum()
|
||||||
|
self._high = self.maximum()
|
||||||
|
|
||||||
|
self.pressed_control = QtWidgets.QStyle.SC_None
|
||||||
|
self.tick_interval = 0
|
||||||
|
self.tick_position = QtWidgets.QSlider.NoTicks
|
||||||
|
self.hover_control = QtWidgets.QStyle.SC_None
|
||||||
|
self.click_offset = 0
|
||||||
|
|
||||||
|
# 0 for the low, 1 for the high, -1 for both
|
||||||
|
self.active_slider = 0
|
||||||
|
|
||||||
|
def low(self):
|
||||||
|
return self._low
|
||||||
|
|
||||||
|
def setLow(self, low:int):
|
||||||
|
self._low = low
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def high(self):
|
||||||
|
return self._high
|
||||||
|
|
||||||
|
def setHigh(self, high):
|
||||||
|
self._high = high
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def paintEvent(self, event):
|
||||||
|
# based on http://qt.gitorious.org/qt/qt/blobs/master/src/gui/widgets/qslider.cpp
|
||||||
|
|
||||||
|
painter = QtGui.QPainter(self)
|
||||||
|
style = QtWidgets.QApplication.style()
|
||||||
|
|
||||||
|
# draw groove
|
||||||
|
opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
opt.siderValue = 0
|
||||||
|
opt.sliderPosition = 0
|
||||||
|
opt.subControls = QtWidgets.QStyle.SC_SliderGroove
|
||||||
|
if self.tickPosition() != self.NoTicks:
|
||||||
|
opt.subControls |= QtWidgets.QStyle.SC_SliderTickmarks
|
||||||
|
style.drawComplexControl(QtWidgets.QStyle.CC_Slider, opt, painter, self)
|
||||||
|
groove = style.subControlRect(QtWidgets.QStyle.CC_Slider, opt, QtWidgets.QStyle.SC_SliderGroove, self)
|
||||||
|
|
||||||
|
# drawSpan
|
||||||
|
#opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
opt.subControls = QtWidgets.QStyle.SC_SliderGroove
|
||||||
|
#if self.tickPosition() != self.NoTicks:
|
||||||
|
# opt.subControls |= QtWidgets.QStyle.SC_SliderTickmarks
|
||||||
|
opt.siderValue = 0
|
||||||
|
#print(self._low)
|
||||||
|
opt.sliderPosition = self._low
|
||||||
|
low_rect = style.subControlRect(QtWidgets.QStyle.CC_Slider, opt, QtWidgets.QStyle.SC_SliderHandle, self)
|
||||||
|
opt.sliderPosition = self._high
|
||||||
|
high_rect = style.subControlRect(QtWidgets.QStyle.CC_Slider, opt, QtWidgets.QStyle.SC_SliderHandle, self)
|
||||||
|
|
||||||
|
#print(low_rect, high_rect)
|
||||||
|
low_pos = self.__pick(low_rect.center())
|
||||||
|
high_pos = self.__pick(high_rect.center())
|
||||||
|
|
||||||
|
min_pos = min(low_pos, high_pos)
|
||||||
|
max_pos = max(low_pos, high_pos)
|
||||||
|
|
||||||
|
c = QtCore.QRect(low_rect.center(), high_rect.center()).center()
|
||||||
|
#print(min_pos, max_pos, c)
|
||||||
|
if opt.orientation == QtCore.Qt.Horizontal:
|
||||||
|
span_rect = QtCore.QRect(QtCore.QPoint(min_pos, c.y()-2), QtCore.QPoint(max_pos, c.y()+1))
|
||||||
|
else:
|
||||||
|
span_rect = QtCore.QRect(QtCore.QPoint(c.x()-2, min_pos), QtCore.QPoint(c.x()+1, max_pos))
|
||||||
|
|
||||||
|
#self.initStyleOption(opt)
|
||||||
|
#print(groove.x(), groove.y(), groove.width(), groove.height())
|
||||||
|
if opt.orientation == QtCore.Qt.Horizontal: groove.adjust(0, 0, -1, 0)
|
||||||
|
else: groove.adjust(0, 0, 0, -1)
|
||||||
|
|
||||||
|
if True: #self.isEnabled():
|
||||||
|
highlight = self.palette().color(QtGui.QPalette.Highlight)
|
||||||
|
painter.setBrush(QtGui.QBrush(highlight))
|
||||||
|
painter.setPen(QtGui.QPen(highlight, 0))
|
||||||
|
#painter.setPen(QtGui.QPen(self.palette().color(QtGui.QPalette.Dark), 0))
|
||||||
|
'''
|
||||||
|
if opt.orientation == QtCore.Qt.Horizontal:
|
||||||
|
self.setupPainter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom())
|
||||||
|
else:
|
||||||
|
self.setupPainter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y())
|
||||||
|
'''
|
||||||
|
#spanRect =
|
||||||
|
painter.drawRect(span_rect.intersected(groove))
|
||||||
|
#painter.drawRect(groove)
|
||||||
|
|
||||||
|
for i, value in enumerate([self._low, self._high]):
|
||||||
|
opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
|
||||||
|
# Only draw the groove for the first slider so it doesn't get drawn
|
||||||
|
# on top of the existing ones every time
|
||||||
|
if i == 0:
|
||||||
|
opt.subControls = QtWidgets.QStyle.SC_SliderHandle# | QtWidgets.QStyle.SC_SliderGroove
|
||||||
|
else:
|
||||||
|
opt.subControls = QtWidgets.QStyle.SC_SliderHandle
|
||||||
|
|
||||||
|
if self.tickPosition() != self.NoTicks:
|
||||||
|
opt.subControls |= QtWidgets.QStyle.SC_SliderTickmarks
|
||||||
|
|
||||||
|
if self.pressed_control:
|
||||||
|
opt.activeSubControls = self.pressed_control
|
||||||
|
else:
|
||||||
|
opt.activeSubControls = self.hover_control
|
||||||
|
|
||||||
|
opt.sliderPosition = value
|
||||||
|
opt.sliderValue = value
|
||||||
|
style.drawComplexControl(QtWidgets.QStyle.CC_Slider, opt, painter, self)
|
||||||
|
|
||||||
|
def mousePressEvent(self, event):
|
||||||
|
event.accept()
|
||||||
|
|
||||||
|
style = QtWidgets.QApplication.style()
|
||||||
|
button = event.button()
|
||||||
|
|
||||||
|
# In a normal slider control, when the user clicks on a point in the
|
||||||
|
# slider's total range, but not on the slider part of the control the
|
||||||
|
# control would jump the slider value to where the user clicked.
|
||||||
|
# For this control, clicks which are not direct hits will slide both
|
||||||
|
# slider parts
|
||||||
|
|
||||||
|
if button:
|
||||||
|
opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
|
||||||
|
self.active_slider = -1
|
||||||
|
|
||||||
|
for i, value in enumerate([self._low, self._high]):
|
||||||
|
opt.sliderPosition = value
|
||||||
|
hit = style.hitTestComplexControl(style.CC_Slider, opt, event.pos(), self)
|
||||||
|
if hit == style.SC_SliderHandle:
|
||||||
|
self.active_slider = i
|
||||||
|
self.pressed_control = hit
|
||||||
|
|
||||||
|
self.triggerAction(self.SliderMove)
|
||||||
|
self.setRepeatAction(self.SliderNoAction)
|
||||||
|
self.setSliderDown(True)
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.active_slider < 0:
|
||||||
|
self.pressed_control = QtWidgets.QStyle.SC_SliderHandle
|
||||||
|
self.click_offset = self.__pixelPosToRangeValue(self.__pick(event.pos()))
|
||||||
|
self.triggerAction(self.SliderMove)
|
||||||
|
self.setRepeatAction(self.SliderNoAction)
|
||||||
|
else:
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
def mouseMoveEvent(self, event):
|
||||||
|
if self.pressed_control != QtWidgets.QStyle.SC_SliderHandle:
|
||||||
|
event.ignore()
|
||||||
|
return
|
||||||
|
|
||||||
|
event.accept()
|
||||||
|
new_pos = self.__pixelPosToRangeValue(self.__pick(event.pos()))
|
||||||
|
opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
|
||||||
|
if self.active_slider < 0:
|
||||||
|
offset = new_pos - self.click_offset
|
||||||
|
self._high += offset
|
||||||
|
self._low += offset
|
||||||
|
if self._low < self.minimum():
|
||||||
|
diff = self.minimum() - self._low
|
||||||
|
self._low += diff
|
||||||
|
self._high += diff
|
||||||
|
if self._high > self.maximum():
|
||||||
|
diff = self.maximum() - self._high
|
||||||
|
self._low += diff
|
||||||
|
self._high += diff
|
||||||
|
elif self.active_slider == 0:
|
||||||
|
if new_pos >= self._high:
|
||||||
|
new_pos = self._high - 1
|
||||||
|
self._low = new_pos
|
||||||
|
else:
|
||||||
|
if new_pos <= self._low:
|
||||||
|
new_pos = self._low + 1
|
||||||
|
self._high = new_pos
|
||||||
|
|
||||||
|
self.click_offset = new_pos
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
#self.emit(QtCore.SIGNAL('sliderMoved(int)'), new_pos)
|
||||||
|
self.sliderMoved.emit(self._low, self._high)
|
||||||
|
|
||||||
|
def __pick(self, pt):
|
||||||
|
if self.orientation() == QtCore.Qt.Horizontal:
|
||||||
|
return pt.x()
|
||||||
|
else:
|
||||||
|
return pt.y()
|
||||||
|
|
||||||
|
|
||||||
|
def __pixelPosToRangeValue(self, pos):
|
||||||
|
opt = QtWidgets.QStyleOptionSlider()
|
||||||
|
self.initStyleOption(opt)
|
||||||
|
style = QtWidgets.QApplication.style()
|
||||||
|
|
||||||
|
gr = style.subControlRect(style.CC_Slider, opt, style.SC_SliderGroove, self)
|
||||||
|
sr = style.subControlRect(style.CC_Slider, opt, style.SC_SliderHandle, self)
|
||||||
|
|
||||||
|
if self.orientation() == QtCore.Qt.Horizontal:
|
||||||
|
slider_length = sr.width()
|
||||||
|
slider_min = gr.x()
|
||||||
|
slider_max = gr.right() - slider_length + 1
|
||||||
|
else:
|
||||||
|
slider_length = sr.height()
|
||||||
|
slider_min = gr.y()
|
||||||
|
slider_max = gr.bottom() - slider_length + 1
|
||||||
|
|
||||||
|
return style.sliderValueFromPosition(self.minimum(), self.maximum(),
|
||||||
|
pos-slider_min, slider_max-slider_min,
|
||||||
|
opt.upsideDown)
|
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource prefix='assets'>
|
||||||
|
<file>bagi_default.png</file>
|
||||||
|
<file>bragi_harp.png</file>
|
||||||
|
<file>cancelX.svg</file>
|
||||||
|
<file>cancel2.svg</file>
|
||||||
|
<file>download.svg</file>
|
||||||
|
<file>play.svg</file>
|
||||||
|
<file>play2.svg</file>
|
||||||
|
<file>stop.svg</file>
|
||||||
|
<file>stop2.svg</file>
|
||||||
|
<file>edit.svg</file>
|
||||||
|
<file>edit2.svg</file>
|
||||||
|
<file>check.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,871 @@
|
|||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import sklearn
|
||||||
|
from sklearn.linear_model import LogisticRegression
|
||||||
|
from sklearn.datasets import load_breast_cancer
|
||||||
|
from sklearn.datasets import make_circles
|
||||||
|
from sklearn.datasets import make_moons
|
||||||
|
from sklearn.datasets import make_classification
|
||||||
|
from sklearn.datasets import load_digits
|
||||||
|
from sklearn.datasets import fetch_openml
|
||||||
|
from sklearn.metrics import accuracy_score, precision_score, recall_score, precision_recall_fscore_support,f1_score
|
||||||
|
from sklearn.metrics import confusion_matrix, roc_curve, roc_auc_score
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
from sklearn.model_selection import KFold
|
||||||
|
from sklearn.model_selection import GridSearchCV
|
||||||
|
from sklearn.tree import DecisionTreeClassifier
|
||||||
|
from sklearn import tree
|
||||||
|
from sklearn.ensemble import RandomForestClassifier
|
||||||
|
from sklearn.neural_network import MLPClassifier
|
||||||
|
from IPython.display import Image
|
||||||
|
|
||||||
|
|
||||||
|
##Funktion zur Berechnung von specificity
|
||||||
|
def specificity_score(y_true, y_pred):
|
||||||
|
p, r, f, s = precision_recall_fscore_support(y_true, y_pred)
|
||||||
|
return r[0]
|
||||||
|
|
||||||
|
##Funktion zum automatisierten Scoring eines Models
|
||||||
|
def score_model(X, y, kf):
|
||||||
|
accuracy_scores = []
|
||||||
|
precision_scores = []
|
||||||
|
recall_scores = []
|
||||||
|
f1_scores = []
|
||||||
|
for train_index, test_index in kf.split(X):
|
||||||
|
X_train, X_test = X[train_index], X[test_index]
|
||||||
|
y_train, y_test = y[train_index], y[test_index]
|
||||||
|
model = LogisticRegression()
|
||||||
|
model.fit(X_train, y_train)
|
||||||
|
y_pred = model.predict(X_test)
|
||||||
|
accuracy_scores.append(accuracy_score(y_test, y_pred))
|
||||||
|
precision_scores.append(precision_score(y_test, y_pred))
|
||||||
|
recall_scores.append(recall_score(y_test, y_pred))
|
||||||
|
f1_scores.append(f1_score(y_test, y_pred))
|
||||||
|
print("accuracy:", np.mean(accuracy_scores))
|
||||||
|
print("precision:", np.mean(precision_scores))
|
||||||
|
print("recall:", np.mean(recall_scores))
|
||||||
|
print("f1 score:", np.mean(f1_scores))
|
||||||
|
|
||||||
|
###
|
||||||
|
# Basics
|
||||||
|
###
|
||||||
|
#Aufgabe 1 numpy/durchschnitt mittelwert
|
||||||
|
#data = [15, 16, 18, 19, 22, 24, 29, 30, 34]
|
||||||
|
|
||||||
|
#print("mean:", np.mean(data))
|
||||||
|
#print("median:", np.median(data))
|
||||||
|
#print("50th percentile (median):", np.percentile(data, 50))
|
||||||
|
#print("25th percentile:", np.percentile(data, 25))
|
||||||
|
#print("75th percentile:", np.percentile(data, 75))
|
||||||
|
#print("standard deviation:", np.std(data))
|
||||||
|
#print("variance:", np.var(data))
|
||||||
|
|
||||||
|
#Aufgabe 2 pandas auslesen Übung
|
||||||
|
#pd.options.display.max_columns = 6
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#print(df.describe())
|
||||||
|
|
||||||
|
#Aufgabe 3 pandas daten manipulation Übung (neue Spalte hinzufügen und benennen 'male')
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#print(df.head())
|
||||||
|
|
||||||
|
#Aufgabe 4 Dataframe Shape übung (Wie ist Dataframe geformt [Anzahl Zeilen,Anzahl Spalten])
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#arr = df[['Pclass', 'Fare', 'Age']].values
|
||||||
|
#print(arr.shape)
|
||||||
|
|
||||||
|
#Aufgabe 5 Summieren von Dataframe Inhalten
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#arr = df[['Pclass', 'Fare', 'Age']].values
|
||||||
|
#mask = arr[:, 2] < 18
|
||||||
|
|
||||||
|
#print(mask.sum())
|
||||||
|
#print((arr[:, 2] < 18).sum())
|
||||||
|
|
||||||
|
#Aufgabe 6 Plotting Übung
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['Gender'] = df['Sex'] == 'male'
|
||||||
|
#plt.scatter(df['Age'], df['Fare'], c=df['Pclass'])
|
||||||
|
|
||||||
|
#plt.xlabel('Age')
|
||||||
|
#plt.ylabel('Fare')
|
||||||
|
|
||||||
|
#cbar = plt.colorbar()
|
||||||
|
#plt.plot([0, 80], [85, 5])
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#2.Beispiel
|
||||||
|
#plt.style.use('fivethirtyeight')
|
||||||
|
|
||||||
|
#fig, ax=plt.subplots()
|
||||||
|
#x=df['Age']
|
||||||
|
#y1=df['Fare']
|
||||||
|
#color=df['Gender']
|
||||||
|
#size=df['Pclass']
|
||||||
|
#ax.scatter(x,y1,c=color,s=30*size,alpha=0.3)
|
||||||
|
#for size in [1,2,3]:
|
||||||
|
# plt.scatter([],[],c='r',s=30*size,label=str(size)+'class')
|
||||||
|
# plt.legend(scatterpoints=1,frameon=False,labelspacing=1,title='Titanic')
|
||||||
|
#ax.set_xlabel('Age')
|
||||||
|
#ax.set_ylabel('Fare')
|
||||||
|
#ax.set_xlim(0,90)
|
||||||
|
#ax.set_ylim(0,555)
|
||||||
|
#cbar = plt.colorbar()
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
###
|
||||||
|
# MachineLearning Algorithms mit Sklearn
|
||||||
|
###
|
||||||
|
|
||||||
|
#Aufgabe 1 Pandas Daten für Model aufbereiten
|
||||||
|
#Ergebnis: x=2D numpy Array(Matrix) aller Features, y=1D NumpyArray des Targets
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
#print(X)
|
||||||
|
#print(y)
|
||||||
|
|
||||||
|
#Aufgabe 2 mit SKLearn Daten "fitten"
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#X = df[['Fare', 'Age']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X, y)
|
||||||
|
|
||||||
|
#print(model.coef_, model.intercept_)
|
||||||
|
# Output sollte sein:[[ 0.01615949 -0.01549065]] [-0.51037152]
|
||||||
|
|
||||||
|
#Aufgabe 3 mit SKLearn und Pandas Targetwerte vorhersagen
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X, y)
|
||||||
|
|
||||||
|
#print(model.predict([[3, True, 22.0, 1, 0, 7.25]]))
|
||||||
|
#print(model.predict(X[:10]))
|
||||||
|
#print(y[:10])
|
||||||
|
|
||||||
|
#y_pred = model.predict(X)
|
||||||
|
#print((y == y_pred).sum()/y.shape[0])
|
||||||
|
#synonym da oft gebraucht:
|
||||||
|
#print(model.score(X, y))
|
||||||
|
# Output Genauigkeit der vorhersagen: 0.8049605411499436
|
||||||
|
|
||||||
|
#print((y == y_pred).sum())
|
||||||
|
#print((y == y_pred).sum() / y.shape[0])
|
||||||
|
#print(model.score(X, y))
|
||||||
|
|
||||||
|
#Aufgabe 4 Model mit vordefiniertem Brust_krebs Datenset
|
||||||
|
#cancer_data = load_breast_cancer()
|
||||||
|
#print(cancer_data.keys())
|
||||||
|
# DESCR (Description ist teil der Daten)
|
||||||
|
#print(cancer_data['DESCR'])
|
||||||
|
|
||||||
|
#print(cancer_data['target'])
|
||||||
|
#print(cancer_data['target'].shape)
|
||||||
|
#print(cancer_data['target_names'])
|
||||||
|
#df = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
|
||||||
|
#df['target'] = cancer_data['target']
|
||||||
|
#print(df.head())
|
||||||
|
|
||||||
|
##feature matrix/target array
|
||||||
|
#X = df[cancer_data.feature_names].values
|
||||||
|
#y = df['target'].values
|
||||||
|
|
||||||
|
##model aufbereiten
|
||||||
|
#model = LogisticRegression(solver='liblinear')
|
||||||
|
#model.fit(X, y)
|
||||||
|
|
||||||
|
#model.predict([X[0]])
|
||||||
|
#print("prediction for datapoint 0:", model.predict([X[0]]))
|
||||||
|
#print(model.score(X, y))
|
||||||
|
|
||||||
|
#Aufgabe 5 Bob der Baumeister
|
||||||
|
##Ziel: Input aus <AnzahlParams>,<matrixAusWerten>,<targetWerteArray>,<DatapointZumTesten>
|
||||||
|
## Output: 1 oder 0
|
||||||
|
|
||||||
|
##Einlesroutine
|
||||||
|
#n = int(input())
|
||||||
|
#X = []
|
||||||
|
#for i in range(n):
|
||||||
|
# X.append([float(x) for x in input().split()])
|
||||||
|
#y = [int(x) for x in input().split()]
|
||||||
|
#testing_datapoint = [float(x) for x in input().split()]
|
||||||
|
|
||||||
|
##Modelbau,fitting und ausgabe
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X, y)
|
||||||
|
#result = model.predict([testing_datapoint])
|
||||||
|
#print(result[0])
|
||||||
|
|
||||||
|
#Aufgabe 6 Metriken mit SKLEARN berechnen
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X, y)
|
||||||
|
#y_pred = model.predict(X)
|
||||||
|
|
||||||
|
##Confusion/Verwirrungs Matrix (Zeigt TN,FP,FN,TP an)
|
||||||
|
#print(confusion_matrix(y, y_pred))
|
||||||
|
|
||||||
|
##Accurcy/Genauigkeit -> Wie oft war die vorhersage richtig (TP+TN)/(TP+FP+FN+TN)
|
||||||
|
#print("accuracy:", accuracy_score(y, y_pred))
|
||||||
|
##Precicion/Präzision -> Verhältnismäßige Anzahl von Falschen Positiven (TP)/(TP+NP)
|
||||||
|
## *Note wenn Precition gegen 1 geht ist die Zahl der FalsePositives niedrig (Interessanter wenn FP gefährlicher/unerwünschter ist)
|
||||||
|
#print("precision:", precision_score(y, y_pred))
|
||||||
|
## Recall/Sensitivity/Sensibilität -> Verhältnismäßige Anzahl von FalseNegatives (TP)/(TP+FN)
|
||||||
|
## *Note wenn recall gegen 1 geht ist die Zahl der FalseNegatives niedrig (Interessant wenn FN gefährlicher/unerwünschter ist)
|
||||||
|
#print("recall:", recall_score(y, y_pred))
|
||||||
|
## F1 Score -> Durchschnitt aus precision und recall
|
||||||
|
## *Note wenn F1 score gegen 1 geht ist die anzahl an FPs und FNs niedrig -> Gute vorhersage im allgemeinen
|
||||||
|
#print("f1 score:", f1_score(y, y_pred))
|
||||||
|
|
||||||
|
#Aufgabe 7 Training Data & Test Data (Verhinderung von Overfitting)
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#train_size-> Prozentanteil des Trainingsets; random_state= randomizer-seed
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y,train_size=0.75,random_state=80613)
|
||||||
|
|
||||||
|
#print("whole dataset:", X.shape, y.shape)
|
||||||
|
#print("training set:", X_train.shape, y_train.shape)
|
||||||
|
#print("test set:", X_test.shape, y_test.shape)
|
||||||
|
|
||||||
|
# building the model
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X_train, y_train)
|
||||||
|
|
||||||
|
# evaluating the model
|
||||||
|
#y_pred = model.predict(X_test)
|
||||||
|
#print("accuracy:", accuracy_score(y_test, y_pred))
|
||||||
|
#print("precision:", precision_score(y_test, y_pred))
|
||||||
|
#print("recall:", recall_score(y_test, y_pred))
|
||||||
|
#print("f1 score:", f1_score(y_test, y_pred))
|
||||||
|
|
||||||
|
#sensitivity_score = recall_score
|
||||||
|
#print("sensitivity:", sensitivity_score(y_test, y_pred))
|
||||||
|
#print("specificity:", specificity_score(y_test, y_pred))
|
||||||
|
|
||||||
|
#Aufgabe 8 Receiver operating characteristic (ROC) Modulieren
|
||||||
|
#*Note ROC-Kurve ist ein Graph der alle möglichen Modelle
|
||||||
|
# und deren Performance anzeigt
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y,train_size=0.75,random_state=80613)
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X_train, y_train)
|
||||||
|
#y_pred_proba = model.predict_proba(X_test)
|
||||||
|
#fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba[:,1])
|
||||||
|
|
||||||
|
#plt.plot(fpr, tpr)
|
||||||
|
#plt.plot([0, 1], [0, 1], linestyle='--')
|
||||||
|
#plt.xlim([0.0, 1.0])
|
||||||
|
#plt.ylim([0.0, 1.0])
|
||||||
|
#plt.xlabel('1 - specificity')
|
||||||
|
#plt.ylabel('sensitivity')
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
##Strategie bei der Auswahl:
|
||||||
|
##Generell gilt je weiter Links oben (hohe Sensitivity+ niedrieger 1-specifity)
|
||||||
|
##desto allgemein besser ist das Model
|
||||||
|
##Je weiter Links
|
||||||
|
##desto mehr von uns positiv vorhergesagte Resultate sind korrekt
|
||||||
|
##Je weiter oben
|
||||||
|
##desto mehr wirklich positive Resultate werden gefunden (FalsePositive Minimierung)
|
||||||
|
|
||||||
|
##Vergleich von 2 ModelVarianten gegen einander
|
||||||
|
#model1 = LogisticRegression()
|
||||||
|
#model1.fit(X_train, y_train)
|
||||||
|
#y_pred_proba1 = model1.predict_proba(X_test)
|
||||||
|
#print("model 1 AUC score:", roc_auc_score(y_test, y_pred_proba1[:, 1]))
|
||||||
|
|
||||||
|
#model2 = LogisticRegression()
|
||||||
|
#model2.fit(X_train[:, 0:2], y_train)
|
||||||
|
#y_pred_proba2 = model2.predict_proba(X_test[:, 0:2])
|
||||||
|
#print("model 2 AUC score:", roc_auc_score(y_test, y_pred_proba2[:, 1]))
|
||||||
|
|
||||||
|
## Vergleich von unterschiedlichen Train/Test Splits gegeneinander
|
||||||
|
#y_pred = model.predict(X_test)
|
||||||
|
#print(" accuracy: {0:.5f}".format(accuracy_score(y_test, y_pred)))
|
||||||
|
#print("precision: {0:.5f}".format(precision_score(y_test, y_pred)))
|
||||||
|
#print(" recall: {0:.5f}".format(recall_score(y_test, y_pred)))
|
||||||
|
#print(" f1 score: {0:.5f}".format(f1_score(y_test, y_pred)))
|
||||||
|
|
||||||
|
#Aufgabe 9 KFold Cross Validierte Modelle erstellen
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#scores = []
|
||||||
|
#kf = KFold(n_splits=5, shuffle=True)
|
||||||
|
|
||||||
|
#for train_index, test_index in kf.split(X):
|
||||||
|
# X_train, X_test = X[train_index], X[test_index]
|
||||||
|
# y_train, y_test = y[train_index], y[test_index]
|
||||||
|
# model = LogisticRegression()
|
||||||
|
# model.fit(X_train, y_train)
|
||||||
|
# scores.append(model.score(X_test, y_test))
|
||||||
|
|
||||||
|
#Finaler Wert der precition aus allen folds(Durchschnitt)
|
||||||
|
#print(scores)
|
||||||
|
#print(np.mean(scores))
|
||||||
|
|
||||||
|
#Aufgabe 10 unterschiedliche Modelle Vergleichen
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
|
||||||
|
#Gleiches KFold CrossValidierungsobjekt
|
||||||
|
#da sonst unfaire Verhältnisse bei den Tests (Gleiche Chunkanzahl)
|
||||||
|
#kf = KFold(n_splits=5, shuffle=True)
|
||||||
|
|
||||||
|
#Verschiedene Modelle mit verschiedenen Featur-Ausprägungen
|
||||||
|
#X1 = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#X2 = df[['Pclass', 'male', 'Age']].values
|
||||||
|
#X3 = df[['Fare', 'Age']].values
|
||||||
|
|
||||||
|
#Ziel numpy array für alle gleich
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#print("Logistic Regression with all features (Model1)")
|
||||||
|
#score_model(X1, y, kf)
|
||||||
|
#print()
|
||||||
|
#print("Logistic Regression with Pclass, Sex & Age features(Model2)")
|
||||||
|
#score_model(X2, y, kf)
|
||||||
|
#print()
|
||||||
|
#print("Logistic Regression with Fare & Age features(Model3)")
|
||||||
|
#score_model(X3, y, kf)
|
||||||
|
|
||||||
|
#Model1 und Model2 haben fast identische Werte
|
||||||
|
#-> Model 2 wäre bessere wahl da weniger features (damit schneller computation)
|
||||||
|
#model = LogisticRegression()
|
||||||
|
#model.fit(X1, y)
|
||||||
|
|
||||||
|
#print(model.predict([[3, False, 25, 0, 1, 2]]))
|
||||||
|
|
||||||
|
#Aufgabe 11 Berechnen von Accuratcy/precision/recall/f1 score
|
||||||
|
#tp, fp, fn, tn = [int(x) for x in input().split()]
|
||||||
|
#total = tp+fp+fn+tn
|
||||||
|
#print(tp)
|
||||||
|
#print(fp)
|
||||||
|
#print(fn)
|
||||||
|
#print(tn)
|
||||||
|
#print(total)
|
||||||
|
#accuracy
|
||||||
|
#accuracy = (tp+tn)/total
|
||||||
|
#print(round(accuracy,4))
|
||||||
|
#precision
|
||||||
|
#precision = (tp)/(tp+fp)
|
||||||
|
#print(round(precision,4))
|
||||||
|
#recal
|
||||||
|
#recall =(tp)/(tp+fn)
|
||||||
|
#print(round(recall,4))
|
||||||
|
#f1 score
|
||||||
|
#f1_score = (2*(precision)*recall)/(precision+recall)
|
||||||
|
#print(round(f1_score,4))
|
||||||
|
|
||||||
|
## ^^^^^^ bis hier hin war logistic regression a.k.a "parametrisches" machine learning
|
||||||
|
####
|
||||||
|
## vvvvvv ab hier entscheidungsbäume (nicht parametisch)
|
||||||
|
|
||||||
|
#Aufgabe 1 Purity (Reinheit) ermitteln
|
||||||
|
#Gini Impurity = 2 x <ProzentZustandA(z.b.survived)> x (1-<ProzentZustandA(und damit nicht survived)>)
|
||||||
|
##-> gini = 2*p*(1-p)
|
||||||
|
#Entropy = -[<ProzentZustandA>*log2<ProzentZustandA>+(1-<ProzentZustandA>)log2(1-<ProzentZustandA>)]
|
||||||
|
##-> entropy = -[plog2p+(1-p)log2(1-p)]
|
||||||
|
## Purity wird in weiteren Formeln mit H abgekürzt/dargestellt
|
||||||
|
|
||||||
|
##Hinweis: Auswahl ob gini oder entropy ist nicht direkt ersichtlich
|
||||||
|
## aber beide können berechnet und abgeglichen werden um beste Modell zu wählen
|
||||||
|
|
||||||
|
#Aufgabe 2 Information Gain aus Purity ermitteln
|
||||||
|
# Formel: Information Gain = H(QuellNode)-((|A|/|QuellNode|)*H(A))-((|B|/|QuellNode|)*H(B))
|
||||||
|
|
||||||
|
#Aufgabe 3 Decision Tree Model erstellen
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
|
||||||
|
#model = DecisionTreeClassifier()
|
||||||
|
#model.fit(X_train, y_train)
|
||||||
|
#print(model.predict([[3, True, 22, 1, 0, 7.25]]))
|
||||||
|
|
||||||
|
#Aufgabe 4 Metriken für Decision Tree ermitteln
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
#X = df[['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#kf = KFold(n_splits=5, shuffle=True, random_state=80613)
|
||||||
|
#dt_accuracy_scores = []
|
||||||
|
#dt_precision_scores = []
|
||||||
|
#dt_recall_scores = []
|
||||||
|
#lr_accuracy_scores = []
|
||||||
|
#lr_precision_scores = []
|
||||||
|
#lr_recall_scores = []
|
||||||
|
#for train_index, test_index in kf.split(X):
|
||||||
|
# X_train, X_test = X[train_index], X[test_index]
|
||||||
|
# y_train, y_test = y[train_index], y[test_index]
|
||||||
|
# dt = DecisionTreeClassifier(criterion='entropy')
|
||||||
|
# dt.fit(X_train, y_train)
|
||||||
|
# dt_accuracy_scores.append(dt.score(X_test, y_test))
|
||||||
|
# dt_y_pred = dt.predict(X_test)
|
||||||
|
# dt_precision_scores.append(precision_score(y_test, dt_y_pred))
|
||||||
|
# dt_recall_scores.append(recall_score(y_test, dt_y_pred))
|
||||||
|
# lr = LogisticRegression()
|
||||||
|
# lr.fit(X_train, y_train)
|
||||||
|
# lr_accuracy_scores.append(lr.score(X_test, y_test))
|
||||||
|
# lr_y_pred = lr.predict(X_test)
|
||||||
|
# lr_precision_scores.append(precision_score(y_test, lr_y_pred))
|
||||||
|
# lr_recall_scores.append(recall_score(y_test, lr_y_pred))
|
||||||
|
#print("Decision Tree")
|
||||||
|
#print(" accuracy:", np.mean(dt_accuracy_scores))
|
||||||
|
#print(" precision:", np.mean(dt_precision_scores))
|
||||||
|
#print(" recall:", np.mean(dt_recall_scores))
|
||||||
|
#print("Logistic Regression")
|
||||||
|
#print(" accuracy:", np.mean(lr_accuracy_scores))
|
||||||
|
#print(" precision:", np.mean(lr_precision_scores))
|
||||||
|
#print(" recall:", np.mean(lr_recall_scores))
|
||||||
|
|
||||||
|
# Vergleich gini vs entropy
|
||||||
|
#for criterion in ['gini', 'entropy']:
|
||||||
|
# print("Decision Tree - {}".format(criterion))
|
||||||
|
# accuracy = []
|
||||||
|
# precision = []
|
||||||
|
# recall = []
|
||||||
|
# for train_index, test_index in kf.split(X):
|
||||||
|
# X_train, X_test = X[train_index], X[test_index]
|
||||||
|
# y_train, y_test = y[train_index], y[test_index]
|
||||||
|
# dt = DecisionTreeClassifier(criterion=criterion)
|
||||||
|
# dt.fit(X_train, y_train)
|
||||||
|
# y_pred = dt.predict(X_test)
|
||||||
|
# accuracy.append(accuracy_score(y_test, y_pred))
|
||||||
|
# precision.append(precision_score(y_test, y_pred))
|
||||||
|
# recall.append(recall_score(y_test, y_pred))
|
||||||
|
# print("accuracy:", np.mean(accuracy))
|
||||||
|
# print("precision:", np.mean(precision))
|
||||||
|
# print("recall:", np.mean(recall), '\n')
|
||||||
|
|
||||||
|
#Aufgabe 5 Entscheidungsbaum Plotten
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
|
||||||
|
#feature_names = ['Pclass', 'male']
|
||||||
|
#X = df[feature_names].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#dt = DecisionTreeClassifier()
|
||||||
|
#dt.fit(X, y)
|
||||||
|
|
||||||
|
#fig = plt.figure(figsize=(10,5))
|
||||||
|
#tree.plot_tree(dt, feature_names=feature_names)
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#Aufgabe 6 Decision-Tree Pruning/Beschneidung
|
||||||
|
#Methode 1 Limitierung der Verzweigungstiefe
|
||||||
|
#Methode 2 Leave/Blatt-Knoten mit geringen Sample-Zahlen vermeiden
|
||||||
|
#Methode 3 Limitierung der Leave/Blatt-Knoten Anzahl
|
||||||
|
|
||||||
|
#BSP:
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
|
||||||
|
#feature_names = ['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']
|
||||||
|
#X = df[feature_names].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#dt = DecisionTreeClassifier(max_depth=3, min_samples_leaf=2, max_leaf_nodes=10)
|
||||||
|
#dt.fit(X, y)
|
||||||
|
|
||||||
|
#fig = plt.figure(figsize=(10,5))
|
||||||
|
#tree.plot_tree(dt, feature_names=feature_names)
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#Aufgabe 7 Finden der Besten Pruning Parameter via GridSearch
|
||||||
|
#df = pd.read_csv('https://sololearn.com/uploads/files/titanic.csv')
|
||||||
|
#df['male'] = df['Sex'] == 'male'
|
||||||
|
|
||||||
|
#feature_names = ['Pclass', 'male', 'Age', 'Siblings/Spouses', 'Parents/Children', 'Fare']
|
||||||
|
#X = df[feature_names].values
|
||||||
|
#y = df['Survived'].values
|
||||||
|
|
||||||
|
#param_grid = {
|
||||||
|
# 'max_depth': [5, 15, 25],
|
||||||
|
# 'min_samples_leaf': [1, 3],
|
||||||
|
# 'max_leaf_nodes': [10, 20, 35, 50]}
|
||||||
|
|
||||||
|
#dt = DecisionTreeClassifier()
|
||||||
|
#gs = GridSearchCV(dt, param_grid, scoring='f1', cv=5)
|
||||||
|
#dt.fit(X, y)
|
||||||
|
#gs.fit(X, y)
|
||||||
|
#print("best params:", gs.best_params_)
|
||||||
|
#print("best score:", gs.best_score_)
|
||||||
|
|
||||||
|
#dt_best = DecisionTreeClassifier(
|
||||||
|
# max_depth=gs.best_params_["max_depth"],
|
||||||
|
# min_samples_leaf=gs.best_params_["min_samples_leaf"],
|
||||||
|
# max_leaf_nodes=gs.best_params_["max_leaf_nodes"])
|
||||||
|
#dt_best.fit(X,y)
|
||||||
|
|
||||||
|
#fig = plt.figure(figsize=(20,10))
|
||||||
|
#tree.plot_tree(dt_best, feature_names=feature_names)
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#Pros/Cons
|
||||||
|
#decision tree ist
|
||||||
|
#-> (+) zeittechnisch teuer zu bauen aber predicttechnisch günstig vorher zu sagen
|
||||||
|
#-> (-vorsicht: ungünstige config verteilt Aussage kraft schlecht auf viele samples a.k.a overfitting weil einzelnes sample zu mächtig
|
||||||
|
#-> (+)einfach zu verstehen und zu erläutern
|
||||||
|
|
||||||
|
#Aufgabe 8 Information Gain ausrechnen
|
||||||
|
|
||||||
|
#S = [int(x) for x in input().split()]
|
||||||
|
#A = [int(x) for x in input().split()]
|
||||||
|
#B = [int(x) for x in input().split()]
|
||||||
|
|
||||||
|
#-> gini = 2*p*(1-p)
|
||||||
|
#Information Gain = H(QuellNode)-((|A|/|QuellNode|)*H(A))-((|B|/|QuellNode|)*H(B))
|
||||||
|
#p_source = S.count(1)/len(S)
|
||||||
|
#q_source = 1 - p_source
|
||||||
|
#gini_source = (2 * p_source * q_source)
|
||||||
|
#print(gini_source)
|
||||||
|
|
||||||
|
#p_left = A.count(1)/len(A)
|
||||||
|
#q_left = 1 - p_left
|
||||||
|
#gini_left = (2 * p_left * q_left)
|
||||||
|
#print(gini_left)
|
||||||
|
|
||||||
|
#p_right = B.count(1)/len(B)
|
||||||
|
#q_right = 1 - p_right
|
||||||
|
#gini_right = (2 * p_right * q_right)
|
||||||
|
#print(gini_right)
|
||||||
|
|
||||||
|
#gain = gini_source - ((len(A)/len(S))*gini_left) - ((len(B)/len(S))*gini_right)
|
||||||
|
#print(round(gain,5))
|
||||||
|
|
||||||
|
|
||||||
|
## ^^^^^^ bis hier hin war entscheidungsbäume a.k.a deciion trees
|
||||||
|
####
|
||||||
|
## vvvvvv ab hier Random Forests
|
||||||
|
|
||||||
|
#Aufgabe 1 Erstellen des Random Forest
|
||||||
|
#cancer_data = load_breast_cancer()
|
||||||
|
#df = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
|
||||||
|
#df['target'] = cancer_data['target']
|
||||||
|
|
||||||
|
#X = df[cancer_data.feature_names].values
|
||||||
|
#y = df['target'].values
|
||||||
|
#print('data dimensions', X.shape)
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
|
||||||
|
#rf = RandomForestClassifier()
|
||||||
|
#rf.fit(X_train, y_train)
|
||||||
|
|
||||||
|
#first_row = X_test[0]
|
||||||
|
#print("prediction:", rf.predict([first_row]))
|
||||||
|
#print("true value:", y_test[0])
|
||||||
|
#print("random forest accuracy:", rf.score(X_test, y_test))
|
||||||
|
|
||||||
|
#dt = DecisionTreeClassifier()
|
||||||
|
#dt.fit(X_train, y_train)
|
||||||
|
#print("decision tree accuracy:", dt.score(X_test, y_test))
|
||||||
|
|
||||||
|
#Aufgabe 2 Random Forest Tuning
|
||||||
|
#cancer_data = load_breast_cancer()
|
||||||
|
#df = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
|
||||||
|
#df['target'] = cancer_data['target']
|
||||||
|
|
||||||
|
#X = df[cancer_data.feature_names].values
|
||||||
|
#y = df['target'].values
|
||||||
|
#print('data dimensions', X.shape)
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
|
||||||
|
#param_grid = {
|
||||||
|
|
||||||
|
# 'n_estimators': [10, 25, 50, 75, 100],
|
||||||
|
|
||||||
|
#}
|
||||||
|
|
||||||
|
#Hinweis default bei RF ist normalerweise "auto" a.k.a SQRT(AnzahlFeatures) -> normalerweise gute Wahl
|
||||||
|
#rf = RandomForestClassifier(max_features=5,n_estimators=15)
|
||||||
|
#rf.fit(X_train, y_train)
|
||||||
|
#rf = RandomForestClassifier(random_state=80613)
|
||||||
|
##Hinweis2 scoring = 'f1' wird meist gewählt wenn Datenset nicht sehr balanciert ist da bei unbalancierten Daten gini/accuracy schlechte ergebnisse liefert
|
||||||
|
#gs = GridSearchCV(rf, param_grid, scoring='f1',cv=5)
|
||||||
|
|
||||||
|
#gs.fit(X,y)
|
||||||
|
#print ("best params:",gs.best_params_)
|
||||||
|
|
||||||
|
#first_row = X_test[0]
|
||||||
|
#print("prediction:", gs.predict([first_row]))
|
||||||
|
#print("true value:", y_test[0])
|
||||||
|
#print("random forest accuracy:", gs.score(X_test, y_test))
|
||||||
|
|
||||||
|
#Aufgabe 3 Plotten von Random Forest mit "Elbow-Graph"
|
||||||
|
#cancer_data = load_breast_cancer()
|
||||||
|
#df = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
|
||||||
|
#df['target'] = cancer_data['target']
|
||||||
|
|
||||||
|
#X = df[cancer_data.feature_names].values
|
||||||
|
#y = df['target'].values
|
||||||
|
#print('data dimensions', X.shape)
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
|
||||||
|
#n_estimators = list(range(1,101))
|
||||||
|
##nach 100er Graph sieht man bei 10 anfang von stagnation -> für verbesserte Performance nur bis hier hin generieren, da weitere Bäume zu wenig dazugewinn sind
|
||||||
|
#n_estimators = list(range(1,10))
|
||||||
|
#param_grid = {
|
||||||
|
|
||||||
|
# 'n_estimators': n_estimators,
|
||||||
|
|
||||||
|
#}
|
||||||
|
|
||||||
|
#rf = RandomForestClassifier(random_state=80613)
|
||||||
|
#gs = GridSearchCV(rf, param_grid, scoring='f1',cv=5)
|
||||||
|
#gs.fit(X,y)
|
||||||
|
#print ("best params:",gs.best_params_)
|
||||||
|
#scores = gs.cv_results_['mean_test_score']
|
||||||
|
|
||||||
|
#first_row = X_test[0]
|
||||||
|
##print("prediction:", gs.predict([first_row]))
|
||||||
|
##print("true value:", y_test[0])
|
||||||
|
##print("random forest accuracy:", gs.score(X_test, y_test))
|
||||||
|
#plt.plot(n_estimators, scores)
|
||||||
|
#plt.xlabel("n_estimators")
|
||||||
|
#plt.ylabel("accuracy")
|
||||||
|
##plt.xlim(0, 100)
|
||||||
|
#plt.xlim(0, 10)
|
||||||
|
#plt.ylim(0.9, 1)
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#Aufgabe 4 Feature Selection (Limitierung der genutzten Feature für Performance)
|
||||||
|
#cancer_data = load_breast_cancer()
|
||||||
|
#df = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
|
||||||
|
#df['target'] = cancer_data['target']
|
||||||
|
|
||||||
|
#X = df[cancer_data.feature_names].values
|
||||||
|
#y = df['target'].values
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
|
||||||
|
#rf = RandomForestClassifier(n_estimators=10, random_state=80613)
|
||||||
|
#rf.fit(X_train, y_train)
|
||||||
|
|
||||||
|
#ft_imp = pd.Series(rf.feature_importances_, index=cancer_data.feature_names).sort_values(ascending=False)
|
||||||
|
#print(ft_imp.head(10))
|
||||||
|
|
||||||
|
##warum ist feature Selection wichtig:
|
||||||
|
##- schnelleres Model Training
|
||||||
|
##- reduziert komplexität
|
||||||
|
##- bei richtiger Feature Wahl -> Verbesserung der Genauigkeit da unnötige Features (Noise) entfernt wird
|
||||||
|
#print(rf.score(X_test, y_test))
|
||||||
|
#worst_cols = [col for col in df.columns if 'worst' in col]
|
||||||
|
#print(worst_cols)
|
||||||
|
|
||||||
|
#X_worst = df[worst_cols]
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X_worst, y, random_state=80613)
|
||||||
|
#rf.fit(X_train, y_train)
|
||||||
|
#print(rf.score(X_test, y_test))
|
||||||
|
|
||||||
|
#Aufgabe 5 Random Forest Pros/Cons Beispiele
|
||||||
|
|
||||||
|
##feature matrix/target array
|
||||||
|
#X, y = make_circles(noise=0.2, factor=0.5, random_state=1)
|
||||||
|
|
||||||
|
#df bauen für plotting anzeige
|
||||||
|
#df = pd.DataFrame(X,columns=["x", "y"])
|
||||||
|
#df['target'] = y
|
||||||
|
#print(df.shape)
|
||||||
|
|
||||||
|
#print("x:",X)
|
||||||
|
#print("y:",y)
|
||||||
|
|
||||||
|
#kf = KFold(n_splits=5, shuffle=True, random_state=1)
|
||||||
|
#lr_scores = []
|
||||||
|
#rf_scores = []
|
||||||
|
#for train_index, test_index in kf.split(X):
|
||||||
|
# X_train, X_test = X[train_index], X[test_index]
|
||||||
|
# y_train, y_test = y[train_index], y[test_index]
|
||||||
|
# lr = LogisticRegression(solver='lbfgs')
|
||||||
|
# lr.fit(X_train, y_train)
|
||||||
|
# lr_scores.append(lr.score(X_test, y_test))
|
||||||
|
# rf = RandomForestClassifier(n_estimators=100)
|
||||||
|
# rf.fit(X_train, y_train)
|
||||||
|
# rf_scores.append(rf.score(X_test, y_test))
|
||||||
|
#print("LR accuracy:", np.mean(lr_scores))
|
||||||
|
#print("RF accuracy:", np.mean(rf_scores))
|
||||||
|
|
||||||
|
#plt.scatter(df["x"],df["y"],c=y)
|
||||||
|
#plt.xlabel('x')
|
||||||
|
#plt.ylabel('y')
|
||||||
|
#cbar = plt.colorbar()
|
||||||
|
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
##Best Practice (Benchmarking):
|
||||||
|
# Bei neuem Classification Problem ist es üblich ein Linear Regression sowie Random Forest Model zu erstellen.
|
||||||
|
# Diese benötigen zu beginn wenig bis kein Tuning um relativ gute Ergebnisse zu liefern.
|
||||||
|
# Es ist so auch direkt ersichtlich welcher Modeltyp eine generel bessere Wahl ist.
|
||||||
|
# Diese Methode gibt erste Anzeichen für mögliche/offensichtliche Optimierungen
|
||||||
|
|
||||||
|
##Aufgabe 6 Übung Aus Input Daten Sätze Random Forest bauen
|
||||||
|
##Param1 Random state für traintestsplit&RF
|
||||||
|
#random_s = int(input())
|
||||||
|
##Param2 Anzahl Datepunkte
|
||||||
|
#n_datapoints = int(input())
|
||||||
|
#rows = []
|
||||||
|
##Param3 Daten für X Array
|
||||||
|
#for i in range(n_datapoints):
|
||||||
|
# rows.append([float(a) for a in input().split()])
|
||||||
|
|
||||||
|
#X = np.array(rows)
|
||||||
|
##Param4 Daten für Target Werte
|
||||||
|
#y = np.array([int(a) for a in input().split()])
|
||||||
|
|
||||||
|
#print("randoms: ",random_s)
|
||||||
|
#print("datapoints: ",n_datapoints)
|
||||||
|
#print("rows: ",rows)
|
||||||
|
#print("X: ",X)
|
||||||
|
#print("y: ",y)
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=random_s)
|
||||||
|
|
||||||
|
#rf = RandomForestClassifier(n_estimators=5,random_state=random_s)
|
||||||
|
#rf.fit(X_train, y_train)
|
||||||
|
#Output Vorhersage mit den Test Set
|
||||||
|
#print(rf.predict(X_test))
|
||||||
|
#print("true value:", y_test[0])
|
||||||
|
|
||||||
|
## ^^^^^^ bis hier hin war Random Forest
|
||||||
|
####
|
||||||
|
## vvvvvv ab hier Neural Networks
|
||||||
|
#Fun Fact: Künstliches Neural Network(ANN) ist biologischem Neural Network im Gehirn Nachempfunden
|
||||||
|
#-> Menschliches Gehirn hat 86 Milliarden Neuronen und ca. 100 Trillionen Synapsen sprich wenn Neurales Netzwerk mehr
|
||||||
|
# als das hat dann ist es vernetzter als ein menschliches Gehirn
|
||||||
|
|
||||||
|
#Basics: Neuronen
|
||||||
|
#3 Activation Funktionen (Funktionen, die Input eines Neurons zu Output wandeln)
|
||||||
|
#A) Sigmoid: 1/(1+e^(-x)) mit x = w1x1 + w2x2 + b-
|
||||||
|
# -> Liefert Output zwischen 0 und 1
|
||||||
|
#B) hyperbolic Tangens: tanh(x) = sinh(x)/cosh(x) = (e^(x) - e^(-x))/(e^(x) + e^(-x))
|
||||||
|
# -> Liefer Output zwischen -1 und 1
|
||||||
|
#C) Rectified Linear Unit: ReLU(x) = {0 wenn x <= 0, x wenn x>0}
|
||||||
|
# -> Liefert Output ab 0 bis x (negativ werte werden geschluckt)
|
||||||
|
|
||||||
|
#Neuronen werden so geformt, dass deren Output oft weiteren Neuronen als Input dient
|
||||||
|
# -> Multi-Layered Perceptron(MLP)
|
||||||
|
# -> Feed Forward (nur in eine Richtung weiter verteilt)
|
||||||
|
|
||||||
|
#Artificial Neural Network (ANN) trainieren
|
||||||
|
# Grundsätzlich immer: Optimieren einer Loss-Funktion
|
||||||
|
# -> Genutzt wird meist cross entropy [p wenn y = 1, 1-p wenn y = 0]
|
||||||
|
|
||||||
|
##Aufgabe 1 Generierung von Random Datensets (für test) + Plotten
|
||||||
|
#X, y = make_classification(n_features=2, n_redundant=0, n_informative=2, random_state=80613)
|
||||||
|
#print(X)
|
||||||
|
#print(y)
|
||||||
|
#plt.scatter(X[y==0][:, 0], X[y==0][:, 1], s=100, edgecolors='k')
|
||||||
|
#plt.scatter(X[y==1][:, 0], X[y==1][:, 1], s=100, edgecolors='k', marker='^')
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
##Aufgabe 2 neural network bauen
|
||||||
|
#X, y = make_classification(n_features=2, n_redundant=0, n_informative=2, random_state=80613)
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
#mlp = MLPClassifier(max_iter=1000,hidden_layer_sizes=(100, 50),alpha=0.0001, solver='adam', random_state=80613)
|
||||||
|
#mlp.fit(X_train, y_train)
|
||||||
|
#print("accuracy:", mlp.score(X_test, y_test))
|
||||||
|
|
||||||
|
##Aufgabe 3 Reale Datensets nutzen (MNIST für Handgeschriebene Zahlen-Zeichen)
|
||||||
|
##Hinweis MNIST Dataset hat Numernzeichen in Grayscale in en Werten 0(schwarz)-16(hellstes Weiß) gespeichert
|
||||||
|
#X, y = load_digits(return_X_y=True)
|
||||||
|
#print(X.shape, y.shape)
|
||||||
|
#print(X[0].reshape(8,8))
|
||||||
|
#print(y[0])
|
||||||
|
|
||||||
|
##matshow zeichnet die Daten von x in einer 8x8 Matrix in der colormap grau an
|
||||||
|
##-> nur nützlich wenn Bilddaten und Bild-Auflösung bekannt ist
|
||||||
|
#plt.matshow(X[1].reshape(8,8),cmap=plt.cm.gray)
|
||||||
|
##xticks und yticks funktionen entferenn die zentrierten coordinaten lineale am Rand
|
||||||
|
#plt.xticks(())
|
||||||
|
#plt.yticks(())
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
#X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=80613)
|
||||||
|
#mlp = MLPClassifier(random_state=80613)
|
||||||
|
#mlp.fit(X_train, y_train)
|
||||||
|
#x = X_test[1]
|
||||||
|
|
||||||
|
#print(mlp.predict([x]))
|
||||||
|
#print(mlp.score(X_test, y_test))
|
||||||
|
|
||||||
|
##prüfen, welche nicht korrekt waren
|
||||||
|
##1) ganzen testsplit vorhersagen lassen
|
||||||
|
##2) vorhersage array nach falsch aussagen filtern und speichern
|
||||||
|
##3) vorhergesagter wert& wahrer wert für anzeige wegspeichern
|
||||||
|
#y_pred = mlp.predict(X_test)
|
||||||
|
#incorrect = X_test[y_pred != y_test]
|
||||||
|
#incorrect_true = y_test[y_pred != y_test]
|
||||||
|
#incorrect_pred = y_pred[y_pred != y_test]
|
||||||
|
|
||||||
|
##ersten anzeigen der nicht korrekt war
|
||||||
|
#j = 0
|
||||||
|
#plt.matshow(incorrect[j].reshape(8,8),cmap=plt.cm.gray)
|
||||||
|
#plt.xticks(())
|
||||||
|
#plt.yticks(())
|
||||||
|
#plt.show()
|
||||||
|
#print("True value: ",incorrect_true[j])
|
||||||
|
#print("predicted value: ",incorrect_pred[j])
|
||||||
|
|
||||||
|
##Aufgabe 4 Visualisierung von MLP-Gewichtung
|
||||||
|
X, y = fetch_openml('mnist_784', version=1, return_X_y=True)
|
||||||
|
#print(X.shape, y.shape)
|
||||||
|
##anzeigen der maximum und minimum werte
|
||||||
|
#print(np.min(X), np.max(X))
|
||||||
|
#print(y[0:5])
|
||||||
|
|
||||||
|
## Wertebereich eingrenzen
|
||||||
|
X5 = X[y <= '3']
|
||||||
|
y5 = y[y <= '3']
|
||||||
|
|
||||||
|
mlp=MLPClassifier(
|
||||||
|
hidden_layer_sizes=(6,),
|
||||||
|
max_iter=200, alpha=1e-4,
|
||||||
|
solver='sgd', random_state=80613)
|
||||||
|
|
||||||
|
mlp.fit(X5, y5)
|
||||||
|
|
||||||
|
## Anzeige der Koeffizenten
|
||||||
|
## -> Anzahl der Layer (meist arrays bei mehreren Knoten welche deren gewichtungen je knoten zeigen[hier zum beispiel 6 knoten bzw deren gewichtungen])
|
||||||
|
print(mlp.coefs_)
|
||||||
|
print(mlp.coefs_[0].shape)
|
||||||
|
|
||||||
|
fig, axes = plt.subplots(2, 3, figsize=(5, 4))
|
||||||
|
|
||||||
|
for i, ax in enumerate(axes.ravel()):
|
||||||
|
coef = mlp.coefs_[0][:, i]
|
||||||
|
ax.matshow(coef.reshape(28, 28), cmap=plt.cm.gray)
|
||||||
|
ax.set_xticks(())
|
||||||
|
ax.set_yticks(())
|
||||||
|
ax.set_title(i + 1)
|
||||||
|
plt.show()
|
@ -0,0 +1,60 @@
|
|||||||
|
# paura_lite:
|
||||||
|
# An ultra-simple command-line audio recorder with real-time
|
||||||
|
# spectrogram visualization
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pyaudio
|
||||||
|
import struct
|
||||||
|
import scipy.fftpack as scp
|
||||||
|
import termplotlib as tpl
|
||||||
|
import os
|
||||||
|
|
||||||
|
# get window's dimensions
|
||||||
|
#rows, columns = os.popen('stty size', 'r').read().split()
|
||||||
|
rows = int(os.popen('mode con | findstr Lines','r').read().strip('\n').strip(' ').split(':')[1].strip(' '))
|
||||||
|
columns = int(os.popen('mode con | findstr Columns','r').read().strip('\n').strip(' ').split(':')[1].strip(' '))
|
||||||
|
|
||||||
|
buff_size = 0.2 # window size in seconds
|
||||||
|
wanted_num_of_bins = 40 # number of frequency bins to display
|
||||||
|
|
||||||
|
# initialize soundcard for recording:
|
||||||
|
fs = 8000
|
||||||
|
pa = pyaudio.PyAudio()
|
||||||
|
stream = pa.open(format=pyaudio.paInt16, channels=1, rate=fs,
|
||||||
|
input=True, frames_per_buffer=int(fs * buff_size))
|
||||||
|
|
||||||
|
while 1: # for each recorded window (until ctr+c) is pressed
|
||||||
|
# get current block and convert to list of short ints,
|
||||||
|
block = stream.read(int(fs * buff_size))
|
||||||
|
format = "%dh" % (len(block) / 2)
|
||||||
|
shorts = struct.unpack(format, block)
|
||||||
|
|
||||||
|
# then normalize and convert to numpy array:
|
||||||
|
x = np.double(list(shorts)) / (2**15)
|
||||||
|
seg_len = len(x)
|
||||||
|
|
||||||
|
# get total energy of the current window and compute a normalization
|
||||||
|
# factor (to be used for visualizing the maximum spectrogram value)
|
||||||
|
energy = np.mean(x ** 2)
|
||||||
|
max_energy = 0.02 # energy for which the bars are set to max
|
||||||
|
max_width_from_energy = int((energy / max_energy) * int(columns)) + 1
|
||||||
|
if max_width_from_energy > int(columns) - 10:
|
||||||
|
max_width_from_energy = int(columns) - 10
|
||||||
|
|
||||||
|
# get the magnitude of the FFT and the corresponding frequencies
|
||||||
|
X = np.abs(scp.fft(x))[0:int(seg_len/2)]
|
||||||
|
freqs = (np.arange(0, 1 + 1.0/len(X), 1.0 / len(X)) * fs / 2)
|
||||||
|
|
||||||
|
# ... and resample to a fix number of frequency bins (to visualize)
|
||||||
|
wanted_step = (int(freqs.shape[0] / wanted_num_of_bins))
|
||||||
|
freqs2 = freqs[0::wanted_step].astype('int')
|
||||||
|
X2 = np.mean(X.reshape(-1, wanted_step), axis=1)
|
||||||
|
|
||||||
|
# plot (freqs, fft) as horizontal histogram:
|
||||||
|
fig = tpl.figure()
|
||||||
|
fig.barh(X2, labels=[str(int(f)) + " Hz" for f in freqs2[0:-1]],
|
||||||
|
show_vals=False, max_width=max_width_from_energy)
|
||||||
|
fig.show()
|
||||||
|
# add exactly as many new lines as they are needed to
|
||||||
|
# fill clear the screen in the next iteration:
|
||||||
|
print("\n" * (int(rows) - freqs2.shape[0] - 1))
|
@ -0,0 +1,125 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.6.4 (~/anaconda3/bin/python3)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="TestRunnerService">
|
||||||
|
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.4 (~/anaconda3/bin/python3)" project-jdk-type="Python SDK" />
|
||||||
|
<component name="PyPackaging">
|
||||||
|
<option name="earlyReleasesAsUpgrades" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Download-Udemy.iml" filepath="$PROJECT_DIR$/.idea/Download-Udemy.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,497 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="993becc6-9ad3-4342-a194-c60d88674714" name="Default Changelist" comment="" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="CoverageDataManager">
|
||||||
|
<SUITE FILE_PATH="coverage/Download_Udemy$str_slicing.coverage" NAME="str_slicing Coverage Results" MODIFIED="1545915784135" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
<SUITE FILE_PATH="coverage/Download_Udemy$index.coverage" NAME="index Coverage Results" MODIFIED="1545915695532" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="FUSProjectUsageTrigger">
|
||||||
|
<session id="938713984">
|
||||||
|
<usages-collector id="statistics.lifecycle.project">
|
||||||
|
<counts>
|
||||||
|
<entry key="project.closed" value="2" />
|
||||||
|
<entry key="project.open.time.2" value="1" />
|
||||||
|
<entry key="project.open.time.4" value="1" />
|
||||||
|
<entry key="project.opened" value="2" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.extensions.open">
|
||||||
|
<counts>
|
||||||
|
<entry key="py" value="2" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.types.open">
|
||||||
|
<counts>
|
||||||
|
<entry key="Python" value="2" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.extensions.edit">
|
||||||
|
<counts>
|
||||||
|
<entry key="py" value="1090" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.types.edit">
|
||||||
|
<counts>
|
||||||
|
<entry key="Python" value="1090" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
</session>
|
||||||
|
<session id="-557085958">
|
||||||
|
<usages-collector id="statistics.lifecycle.project">
|
||||||
|
<counts>
|
||||||
|
<entry key="project.closed" value="4" />
|
||||||
|
<entry key="project.open.time.0" value="1" />
|
||||||
|
<entry key="project.open.time.4" value="1" />
|
||||||
|
<entry key="project.open.time.5" value="2" />
|
||||||
|
<entry key="project.opened" value="4" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.extensions.edit">
|
||||||
|
<counts>
|
||||||
|
<entry key="py" value="3931" />
|
||||||
|
<entry key="qrc" value="72" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.types.edit">
|
||||||
|
<counts>
|
||||||
|
<entry key="Python" value="3931" />
|
||||||
|
<entry key="XML" value="72" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.extensions.open">
|
||||||
|
<counts>
|
||||||
|
<entry key="css" value="4" />
|
||||||
|
<entry key="py" value="1" />
|
||||||
|
<entry key="qrc" value="1" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
<usages-collector id="statistics.file.types.open">
|
||||||
|
<counts>
|
||||||
|
<entry key="CSS" value="4" />
|
||||||
|
<entry key="Python" value="1" />
|
||||||
|
<entry key="XML" value="1" />
|
||||||
|
</counts>
|
||||||
|
</usages-collector>
|
||||||
|
</session>
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/index.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="222">
|
||||||
|
<caret line="62" lean-forward="true" selection-start-line="62" selection-end-line="62" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="496:505" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="1842:1851" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="2144:2153" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="3440:3449" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="3691:4514" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="4539:5060" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="5602:6786" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7239:7403" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7506:7554" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7885:8007" ph="..." />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/index copy.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="380">
|
||||||
|
<caret line="122" lean-forward="true" selection-start-line="122" selection-end-line="122" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/index copy 2.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="261">
|
||||||
|
<caret line="84" selection-start-line="84" selection-end-line="86" selection-end-column="27" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/qdark.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1364">
|
||||||
|
<caret line="62" column="21" selection-start-line="62" selection-start-column="21" selection-end-line="62" selection-end-column="21" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/qdarkgray.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="393">
|
||||||
|
<caret line="36" column="23" selection-start-line="36" selection-start-column="23" selection-end-line="36" selection-end-column="29" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/darkblu.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="990">
|
||||||
|
<caret line="45" column="15" selection-start-line="45" selection-start-column="15" selection-end-line="45" selection-end-column="15" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/photo.qrc">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="242">
|
||||||
|
<caret line="11" column="32" selection-start-line="11" selection-start-column="32" selection-end-line="11" selection-end-column="32" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/str_slicing.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="44">
|
||||||
|
<caret line="2" column="88" selection-start-line="2" selection-start-column="83" selection-end-line="2" selection-end-column="88" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/testData.txt">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state>
|
||||||
|
<caret column="30" selection-end-line="1" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Python Script" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/str_slicing.py" />
|
||||||
|
<option value="$PROJECT_DIR$/photo.qrc" />
|
||||||
|
<option value="$PROJECT_DIR$/themes/qdark.css" />
|
||||||
|
<option value="$PROJECT_DIR$/themes/qdarkgray.css" />
|
||||||
|
<option value="$PROJECT_DIR$/themes/darkorange.css" />
|
||||||
|
<option value="$PROJECT_DIR$/themes/darkblu.css" />
|
||||||
|
<option value="$PROJECT_DIR$/index.py" />
|
||||||
|
<option value="$PROJECT_DIR$/index copy.py" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||||
|
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||||
|
<component name="JsGulpfileManager">
|
||||||
|
<detection-done>true</detection-done>
|
||||||
|
<sorting>DEFINITION_ORDER</sorting>
|
||||||
|
</component>
|
||||||
|
<component name="NodePackageJsonFileManager">
|
||||||
|
<packageJsonPaths />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds" fullScreen="true">
|
||||||
|
<option name="x" value="-92" />
|
||||||
|
<option name="y" value="23" />
|
||||||
|
<option name="width" value="1440" />
|
||||||
|
<option name="height" value="833" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator proportions="" version="1">
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="Download-Udemy" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="Download-Udemy" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
|
||||||
|
</component>
|
||||||
|
<component name="PyConsoleOptionsProvider">
|
||||||
|
<option name="myPythonConsoleState">
|
||||||
|
<console-settings module-name="Download-Udemy" is-module-sdk="true">
|
||||||
|
<envs>
|
||||||
|
<env key="PAFY_BACKEND" value="internal" />
|
||||||
|
</envs>
|
||||||
|
<option name="myUseModuleSdk" value="true" />
|
||||||
|
<option name="myModuleName" value="Download-Udemy" />
|
||||||
|
<option name="myEnvs">
|
||||||
|
<map>
|
||||||
|
<entry key="PAFY_BACKEND" value="internal" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</console-settings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager" selected="Python.index copy">
|
||||||
|
<configuration name="index copy" type="PythonConfigurationType" factoryName="Python" temporary="true">
|
||||||
|
<module name="Download-Udemy" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/index copy.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="index" type="PythonConfigurationType" factoryName="Python" temporary="true">
|
||||||
|
<module name="Download-Udemy" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="$USER_HOME$/anaconda3/bin/python3" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="false" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/index.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="str_slicing" type="PythonConfigurationType" factoryName="Python" temporary="true">
|
||||||
|
<module name="Download-Udemy" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/str_slicing.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.index" />
|
||||||
|
<item itemvalue="Python.str_slicing" />
|
||||||
|
<item itemvalue="Python.index copy" />
|
||||||
|
</list>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.index copy" />
|
||||||
|
<item itemvalue="Python.index" />
|
||||||
|
<item itemvalue="Python.str_slicing" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SvnConfiguration">
|
||||||
|
<configuration />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="993becc6-9ad3-4342-a194-c60d88674714" name="Default Changelist" comment="" />
|
||||||
|
<created>1540491261099</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1540491261099</updated>
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="0" y="0" width="1440" height="900" extended-state="0" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.20789288" />
|
||||||
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
|
<window_info id="Favorites" order="2" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
|
<window_info anchor="bottom" id="Find" order="1" />
|
||||||
|
<window_info anchor="bottom" id="Run" order="2" weight="0.26506025" />
|
||||||
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="bottom" id="Version Control" order="7" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Terminal" order="8" weight="0.32793522" />
|
||||||
|
<window_info anchor="bottom" id="Event Log" order="9" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Docker" order="10" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Database Changes" order="11" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Python Console" order="12" weight="0.32793522" />
|
||||||
|
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||||
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
|
<window_info anchor="right" id="SciView" order="3" />
|
||||||
|
<window_info anchor="right" id="Database" order="4" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="VcsContentAnnotationSettings">
|
||||||
|
<option name="myLimit" value="2678400000" />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/photo_rc.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-17355" />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/qdark.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1364">
|
||||||
|
<caret line="62" column="21" selection-start-line="62" selection-start-column="21" selection-end-line="62" selection-end-column="21" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/darkblu.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="990">
|
||||||
|
<caret line="45" column="15" selection-start-line="45" selection-start-column="15" selection-end-line="45" selection-end-column="15" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/photo.qrc">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="242">
|
||||||
|
<caret line="11" column="32" selection-start-line="11" selection-start-column="32" selection-end-line="11" selection-end-column="32" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/darkorange.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="264">
|
||||||
|
<caret line="12" column="29" selection-start-line="12" selection-start-column="23" selection-end-line="12" selection-end-column="29" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/themes/qdarkgray.css">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="393">
|
||||||
|
<caret line="36" column="23" selection-start-line="36" selection-start-column="23" selection-end-line="36" selection-end-column="29" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/str_slicing.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="44">
|
||||||
|
<caret line="2" column="88" selection-start-line="2" selection-start-column="83" selection-end-line="2" selection-end-column="88" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/index.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="222">
|
||||||
|
<caret line="62" lean-forward="true" selection-start-line="62" selection-end-line="62" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="496:505" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="1842:1851" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="2144:2153" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="3440:3449" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="3691:4514" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="4539:5060" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="5602:6786" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7239:7403" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7506:7554" ph="..." />
|
||||||
|
<marker date="1557562730652" expanded="true" signature="7885:8007" ph="..." />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/index copy 2.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="261">
|
||||||
|
<caret line="84" selection-start-line="84" selection-end-line="86" selection-end-column="27" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/testData.txt">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state>
|
||||||
|
<caret column="30" selection-end-line="1" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/index copy.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="380">
|
||||||
|
<caret line="122" lean-forward="true" selection-start-line="122" selection-end-line="122" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#25#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,16 @@
|
|||||||
|
# PyQt5-Download-Manager
|
||||||
|
PyQt5 simple files , youtube videos and youtube playlist downloader
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
> ### Project Files :
|
||||||
|
- index.py : the main project file , use it to run the project
|
||||||
|
- main.py : this is the UI file converted to python code
|
||||||
|
- main.ui : the UI file , you can edit it in the QtDesigner
|
||||||
|
- photo.qrc : the qresource file which contains the icons paths
|
||||||
|
- photo_rc.py : the icons files converted to python code
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
> ### How To Run The Code :
|
||||||
|
first you have to make sure that you have python3 and PyQt5 installed
|
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 672 B |
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1,321 @@
|
|||||||
|
from PyQt5.QtGui import *
|
||||||
|
from PyQt5.QtCore import *
|
||||||
|
from PyQt5.QtWidgets import *
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PyQt5.uic import loadUiType
|
||||||
|
import urllib.request
|
||||||
|
#import pafy
|
||||||
|
#import humanize
|
||||||
|
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
|
||||||
|
ui,_ = loadUiType('main.ui')
|
||||||
|
|
||||||
|
class MainApp(QMainWindow , ui):
|
||||||
|
def __init__(self , parent=None):
|
||||||
|
super(MainApp , self).__init__(parent)
|
||||||
|
QMainWindow.__init__(self)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.InitUI()
|
||||||
|
self.Handel_Buttons()
|
||||||
|
|
||||||
|
|
||||||
|
def InitUI(self):
|
||||||
|
## contain all ui changes in loading
|
||||||
|
self.tabWidget.tabBar().setVisible(False)
|
||||||
|
self.Apply_DarkOrange_Style()
|
||||||
|
|
||||||
|
self.Move_Box_1()
|
||||||
|
self.Move_Box_2()
|
||||||
|
self.Move_Box_3()
|
||||||
|
self.Move_Box_4()
|
||||||
|
|
||||||
|
|
||||||
|
def Handel_Buttons(self):
|
||||||
|
## handel all buttons in the app
|
||||||
|
self.pushButton.clicked.connect(self.Download)
|
||||||
|
self.pushButton_2.clicked.connect(self.Handel_Browse)
|
||||||
|
|
||||||
|
self.pushButton_5.clicked.connect(self.Get_Video_Data)
|
||||||
|
self.pushButton_4.clicked.connect(self.Download_Video)
|
||||||
|
self.pushButton_3.clicked.connect(self.Save_Browse)
|
||||||
|
|
||||||
|
self.pushButton_7.clicked.connect(self.Playlist_Download)
|
||||||
|
self.pushButton_6.clicked.connect(self.Playlist_Save_Browse)
|
||||||
|
|
||||||
|
self.pushButton_8.clicked.connect(self.Open_Home)
|
||||||
|
self.pushButton_9.clicked.connect(self.Open_Download)
|
||||||
|
self.pushButton_11.clicked.connect(self.Open_Youtube)
|
||||||
|
self.pushButton_10.clicked.connect(self.Open_Settings)
|
||||||
|
|
||||||
|
|
||||||
|
self.pushButton_12.clicked.connect(self.Apply_DarkOrange_Style)
|
||||||
|
self.pushButton_13.clicked.connect(self.Apply_DarkGray_Style)
|
||||||
|
self.pushButton_14.clicked.connect(self.Apply_QDark_Style)
|
||||||
|
self.pushButton_15.clicked.connect(self.Apply_QDarkBlue_Style)
|
||||||
|
|
||||||
|
def Handel_Progress(self , blocknum , blocksize , totalsize):
|
||||||
|
## calculate the progress
|
||||||
|
readed_data = blocknum * blocksize
|
||||||
|
|
||||||
|
if totalsize > 0 :
|
||||||
|
download_percentage = readed_data * 100 / totalsize
|
||||||
|
self.progressBar.setValue(download_percentage)
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Handel_Browse(self):
|
||||||
|
## enable browseing to our os , pick save location
|
||||||
|
save_location = QFileDialog.getSaveFileName(self , caption="Save as" , directory="." , filter="All Files(*.*)")
|
||||||
|
print(save_location)
|
||||||
|
self.lineEdit_2.setText(str(save_location[0]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Download(self):
|
||||||
|
## downloading any file
|
||||||
|
print('Start Download')
|
||||||
|
|
||||||
|
download_url = self.lineEdit.text()
|
||||||
|
save_location = self.lineEdit_2.text()
|
||||||
|
|
||||||
|
if download_url == '' or save_location == '':
|
||||||
|
QMessageBox.warning(self , "Data Error" , "Provide a valid URL or save location")
|
||||||
|
else:
|
||||||
|
|
||||||
|
try:
|
||||||
|
urllib.request.urlretrieve(download_url , save_location , self.Handel_Progress)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
QMessageBox.warning(self, "Download Error", "Provide a valid URL or save location")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
QMessageBox.information(self , "Download Completed" , "The Download Completed Successfully ")
|
||||||
|
|
||||||
|
self.lineEdit.setText('')
|
||||||
|
self.lineEdit_2.setText('')
|
||||||
|
self.progressBar.setValue(0)
|
||||||
|
|
||||||
|
|
||||||
|
def Save_Browse(self):
|
||||||
|
## save location in the line edit
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
##############################################
|
||||||
|
######## Download Youtube Single Video
|
||||||
|
def Save_Browse(self):
|
||||||
|
## save location in the line edit
|
||||||
|
save_location = QFileDialog.getSaveFileName(self , caption="Save as" , directory="." , filter="All Files(*.*)")
|
||||||
|
|
||||||
|
|
||||||
|
self.lineEdit_4.setText(str(save_location[0]))
|
||||||
|
|
||||||
|
|
||||||
|
def Get_Video_Data(self):
|
||||||
|
|
||||||
|
video_url = self.lineEdit_3.text()
|
||||||
|
print(video_url)
|
||||||
|
|
||||||
|
if video_url == '' :
|
||||||
|
QMessageBox.warning(self, "Data Error", "Provide a valid Video URL")
|
||||||
|
|
||||||
|
else:
|
||||||
|
video = pafy.new(video_url)
|
||||||
|
print(video.title)
|
||||||
|
print(video.duration)
|
||||||
|
print(video.author)
|
||||||
|
print(video.length)
|
||||||
|
print(video.viewcount)
|
||||||
|
print(video.likes)
|
||||||
|
print(video.dislikes)
|
||||||
|
|
||||||
|
video_streams = video.videostreams
|
||||||
|
for stream in video_streams :
|
||||||
|
print(stream.get_filesize())
|
||||||
|
size = humanize.naturalsize(stream.get_filesize())
|
||||||
|
data = "{} {} {} {}".format(stream.mediatype , stream.extension , stream.quality , size)
|
||||||
|
self.comboBox.addItem(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Download_Video(self):
|
||||||
|
video_url = self.lineEdit_3.text()
|
||||||
|
save_location = self.lineEdit_4.text()
|
||||||
|
|
||||||
|
if video_url == '' or save_location == '':
|
||||||
|
QMessageBox.warning(self, "Data Error", "Provide a valid Video URL or save location")
|
||||||
|
|
||||||
|
else:
|
||||||
|
video = pafy.new(video_url)
|
||||||
|
video_stream = video.videostreams
|
||||||
|
video_quality = self.comboBox.currentIndex()
|
||||||
|
download = video_stream[video_quality].download(filepath=save_location , callback=self.Video_Progress)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Video_Progress(self , total , received , ratio , rate , time):
|
||||||
|
read_data = received
|
||||||
|
if total > 0 :
|
||||||
|
download_percentage = read_data * 100 / total
|
||||||
|
self.progressBar_2.setValue(download_percentage)
|
||||||
|
remaining_time = round(time/60 , 2)
|
||||||
|
|
||||||
|
self.label_5.setText(str('{} minutes remaining'.format(remaining_time)))
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################################################
|
||||||
|
######### Youtube Playlist Download
|
||||||
|
|
||||||
|
def Playlist_Download(self):
|
||||||
|
playlist_url = self.lineEdit_5.text()
|
||||||
|
save_location = self.lineEdit_6.text()
|
||||||
|
|
||||||
|
if playlist_url == '' or save_location == '' :
|
||||||
|
QMessageBox.warning(self, "Data Error", "Provide a valid Playlist URL or save location")
|
||||||
|
|
||||||
|
else:
|
||||||
|
playlist = pafy.get_playlist(playlist_url)
|
||||||
|
playlist_videos = playlist['items']
|
||||||
|
|
||||||
|
self.lcdNumber_2.display(len(playlist_videos))
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir(save_location)
|
||||||
|
if os.path.exists(str(playlist['title'])):
|
||||||
|
os.chdir(str(playlist['title']))
|
||||||
|
|
||||||
|
else:
|
||||||
|
os.mkdir(str(playlist['title']))
|
||||||
|
os.chdir(str(playlist['title']))
|
||||||
|
|
||||||
|
current_video_in_download = 1
|
||||||
|
quality = self.comboBox_2.currentIndex()
|
||||||
|
|
||||||
|
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
for video in playlist_videos :
|
||||||
|
current_video = video['pafy']
|
||||||
|
current_video_stream = current_video.videostreams
|
||||||
|
self.lcdNumber.display(current_video_in_download)
|
||||||
|
download = current_video_stream[quality].download(callback=self.Playlist_Progress)
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
current_video_in_download +=1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Playlist_Progress(self , total , received , ratio , rate , time):
|
||||||
|
read_data = received
|
||||||
|
if total > 0 :
|
||||||
|
download_percentage = read_data * 100 / total
|
||||||
|
self.progressBar_3.setValue(download_percentage)
|
||||||
|
remaining_time = round(time/60 , 2)
|
||||||
|
|
||||||
|
self.label_6.setText(str('{} minutes remaining'.format(remaining_time)))
|
||||||
|
QApplication.processEvents()
|
||||||
|
|
||||||
|
|
||||||
|
def Playlist_Save_Browse(self):
|
||||||
|
playlist_save_location = QFileDialog.getExistingDirectory(self , "Select Download Directory")
|
||||||
|
self.lineEdit_6.setText(playlist_save_location)
|
||||||
|
|
||||||
|
################################################
|
||||||
|
###### UI CHanges Methods
|
||||||
|
def Open_Home(self):
|
||||||
|
self.tabWidget.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def Open_Download(self):
|
||||||
|
self.tabWidget.setCurrentIndex(1)
|
||||||
|
|
||||||
|
def Open_Youtube(self):
|
||||||
|
self.tabWidget.setCurrentIndex(2)
|
||||||
|
|
||||||
|
|
||||||
|
def Open_Settings(self):
|
||||||
|
self.tabWidget.setCurrentIndex(3)
|
||||||
|
|
||||||
|
|
||||||
|
################################################
|
||||||
|
###### App Themes ####
|
||||||
|
|
||||||
|
def Apply_DarkOrange_Style(self):
|
||||||
|
style = open('themes/darkorange.css' , 'r')
|
||||||
|
style = style.read()
|
||||||
|
self.setStyleSheet(style)
|
||||||
|
|
||||||
|
|
||||||
|
def Apply_QDark_Style(self):
|
||||||
|
style = open('themes/qdark.css' , 'r')
|
||||||
|
style = style.read()
|
||||||
|
self.setStyleSheet(style)
|
||||||
|
|
||||||
|
|
||||||
|
def Apply_DarkGray_Style(self):
|
||||||
|
style = open('themes/qdarkgray.css' , 'r')
|
||||||
|
style = style.read()
|
||||||
|
self.setStyleSheet(style)
|
||||||
|
|
||||||
|
def Apply_QDarkBlue_Style(self):
|
||||||
|
style = open('themes/darkblu.css' , 'r')
|
||||||
|
style = style.read()
|
||||||
|
self.setStyleSheet(style)
|
||||||
|
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
####### App Animation
|
||||||
|
|
||||||
|
def Move_Box_1(self):
|
||||||
|
box_animation1 = QPropertyAnimation(self.groupBox , b"geometry")
|
||||||
|
box_animation1.setDuration(2500)
|
||||||
|
box_animation1.setStartValue(QRect(0,0,0,0))
|
||||||
|
box_animation1.setEndValue(QRect(60,40,281,141))
|
||||||
|
box_animation1.start()
|
||||||
|
self.box_animation1 = box_animation1
|
||||||
|
|
||||||
|
|
||||||
|
def Move_Box_2(self):
|
||||||
|
box_animation2 = QPropertyAnimation(self.groupBox_2 , b"geometry")
|
||||||
|
box_animation2.setDuration(2500)
|
||||||
|
box_animation2.setStartValue(QRect(0,0,0,0))
|
||||||
|
box_animation2.setEndValue(QRect(380,40,281,141))
|
||||||
|
box_animation2.start()
|
||||||
|
self.box_animation2 = box_animation2
|
||||||
|
|
||||||
|
|
||||||
|
def Move_Box_3(self):
|
||||||
|
box_animation3 = QPropertyAnimation(self.groupBox_3 , b"geometry")
|
||||||
|
box_animation3.setDuration(2500)
|
||||||
|
box_animation3.setStartValue(QRect(0,0,0,0))
|
||||||
|
box_animation3.setEndValue(QRect(60,210,281,141))
|
||||||
|
box_animation3.start()
|
||||||
|
self.box_animation3 = box_animation3
|
||||||
|
|
||||||
|
|
||||||
|
def Move_Box_4(self):
|
||||||
|
box_animation4 = QPropertyAnimation(self.groupBox_4 , b"geometry")
|
||||||
|
box_animation4.setDuration(2500)
|
||||||
|
box_animation4.setStartValue(QRect(0,0,0,0))
|
||||||
|
box_animation4.setEndValue(QRect(380,210,281,141))
|
||||||
|
box_animation4.start()
|
||||||
|
self.box_animation4 = box_animation4
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
window = MainApp()
|
||||||
|
window.show()
|
||||||
|
app.exec_()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,212 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'main.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.9.2
|
||||||
|
#
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(752, 391)
|
||||||
|
icon = QtGui.QIcon()
|
||||||
|
icon.addPixmap(QtGui.QPixmap(":/icons/check.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
|
MainWindow.setWindowIcon(icon)
|
||||||
|
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
|
||||||
|
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 751, 341))
|
||||||
|
self.tabWidget.setObjectName("tabWidget")
|
||||||
|
self.tab = QtWidgets.QWidget()
|
||||||
|
self.tab.setObjectName("tab")
|
||||||
|
self.pushButton = QtWidgets.QPushButton(self.tab)
|
||||||
|
self.pushButton.setGeometry(QtCore.QRect(310, 221, 131, 51))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(16)
|
||||||
|
self.pushButton.setFont(font)
|
||||||
|
self.pushButton.setObjectName("pushButton")
|
||||||
|
self.lineEdit = QtWidgets.QLineEdit(self.tab)
|
||||||
|
self.lineEdit.setGeometry(QtCore.QRect(130, 60, 521, 31))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit.setFont(font)
|
||||||
|
self.lineEdit.setObjectName("lineEdit")
|
||||||
|
self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)
|
||||||
|
self.lineEdit_2.setGeometry(QtCore.QRect(130, 100, 471, 31))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit_2.setFont(font)
|
||||||
|
self.lineEdit_2.setObjectName("lineEdit_2")
|
||||||
|
self.pushButton_2 = QtWidgets.QPushButton(self.tab)
|
||||||
|
self.pushButton_2.setGeometry(QtCore.QRect(600, 100, 51, 41))
|
||||||
|
self.pushButton_2.setText("")
|
||||||
|
icon1 = QtGui.QIcon()
|
||||||
|
icon1.addPixmap(QtGui.QPixmap(":/icons/browse.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
|
self.pushButton_2.setIcon(icon1)
|
||||||
|
self.pushButton_2.setIconSize(QtCore.QSize(33, 33))
|
||||||
|
self.pushButton_2.setObjectName("pushButton_2")
|
||||||
|
self.progressBar = QtWidgets.QProgressBar(self.tab)
|
||||||
|
self.progressBar.setGeometry(QtCore.QRect(130, 160, 521, 23))
|
||||||
|
self.progressBar.setProperty("value", 0)
|
||||||
|
self.progressBar.setObjectName("progressBar")
|
||||||
|
self.tabWidget.addTab(self.tab, "")
|
||||||
|
self.tab_2 = QtWidgets.QWidget()
|
||||||
|
self.tab_2.setObjectName("tab_2")
|
||||||
|
self.tabWidget_2 = QtWidgets.QTabWidget(self.tab_2)
|
||||||
|
self.tabWidget_2.setGeometry(QtCore.QRect(10, 0, 731, 311))
|
||||||
|
self.tabWidget_2.setObjectName("tabWidget_2")
|
||||||
|
self.tab_3 = QtWidgets.QWidget()
|
||||||
|
self.tab_3.setObjectName("tab_3")
|
||||||
|
self.lineEdit_3 = QtWidgets.QLineEdit(self.tab_3)
|
||||||
|
self.lineEdit_3.setGeometry(QtCore.QRect(110, 20, 451, 41))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit_3.setFont(font)
|
||||||
|
self.lineEdit_3.setObjectName("lineEdit_3")
|
||||||
|
self.lineEdit_4 = QtWidgets.QLineEdit(self.tab_3)
|
||||||
|
self.lineEdit_4.setGeometry(QtCore.QRect(110, 70, 451, 41))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit_4.setFont(font)
|
||||||
|
self.lineEdit_4.setObjectName("lineEdit_4")
|
||||||
|
self.pushButton_3 = QtWidgets.QPushButton(self.tab_3)
|
||||||
|
self.pushButton_3.setGeometry(QtCore.QRect(560, 70, 61, 51))
|
||||||
|
self.pushButton_3.setText("")
|
||||||
|
self.pushButton_3.setIcon(icon1)
|
||||||
|
self.pushButton_3.setIconSize(QtCore.QSize(33, 33))
|
||||||
|
self.pushButton_3.setObjectName("pushButton_3")
|
||||||
|
self.progressBar_2 = QtWidgets.QProgressBar(self.tab_3)
|
||||||
|
self.progressBar_2.setGeometry(QtCore.QRect(130, 170, 491, 23))
|
||||||
|
self.progressBar_2.setProperty("value", 0)
|
||||||
|
self.progressBar_2.setObjectName("progressBar_2")
|
||||||
|
self.pushButton_4 = QtWidgets.QPushButton(self.tab_3)
|
||||||
|
self.pushButton_4.setGeometry(QtCore.QRect(260, 220, 211, 32))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
self.pushButton_4.setFont(font)
|
||||||
|
self.pushButton_4.setObjectName("pushButton_4")
|
||||||
|
self.label = QtWidgets.QLabel(self.tab_3)
|
||||||
|
self.label.setGeometry(QtCore.QRect(160, 130, 131, 31))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
self.label.setFont(font)
|
||||||
|
self.label.setObjectName("label")
|
||||||
|
self.comboBox = QtWidgets.QComboBox(self.tab_3)
|
||||||
|
self.comboBox.setGeometry(QtCore.QRect(290, 130, 281, 41))
|
||||||
|
self.comboBox.setObjectName("comboBox")
|
||||||
|
self.pushButton_5 = QtWidgets.QPushButton(self.tab_3)
|
||||||
|
self.pushButton_5.setGeometry(QtCore.QRect(560, 20, 61, 51))
|
||||||
|
self.pushButton_5.setText("")
|
||||||
|
self.pushButton_5.setIcon(icon)
|
||||||
|
self.pushButton_5.setIconSize(QtCore.QSize(33, 33))
|
||||||
|
self.pushButton_5.setObjectName("pushButton_5")
|
||||||
|
self.tabWidget_2.addTab(self.tab_3, "")
|
||||||
|
self.tab_4 = QtWidgets.QWidget()
|
||||||
|
self.tab_4.setObjectName("tab_4")
|
||||||
|
self.lineEdit_5 = QtWidgets.QLineEdit(self.tab_4)
|
||||||
|
self.lineEdit_5.setGeometry(QtCore.QRect(120, 20, 501, 31))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit_5.setFont(font)
|
||||||
|
self.lineEdit_5.setObjectName("lineEdit_5")
|
||||||
|
self.lineEdit_6 = QtWidgets.QLineEdit(self.tab_4)
|
||||||
|
self.lineEdit_6.setGeometry(QtCore.QRect(120, 60, 451, 31))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.lineEdit_6.setFont(font)
|
||||||
|
self.lineEdit_6.setObjectName("lineEdit_6")
|
||||||
|
self.pushButton_6 = QtWidgets.QPushButton(self.tab_4)
|
||||||
|
self.pushButton_6.setGeometry(QtCore.QRect(570, 60, 51, 41))
|
||||||
|
self.pushButton_6.setText("")
|
||||||
|
self.pushButton_6.setIcon(icon1)
|
||||||
|
self.pushButton_6.setIconSize(QtCore.QSize(33, 33))
|
||||||
|
self.pushButton_6.setObjectName("pushButton_6")
|
||||||
|
self.progressBar_3 = QtWidgets.QProgressBar(self.tab_4)
|
||||||
|
self.progressBar_3.setGeometry(QtCore.QRect(120, 200, 511, 23))
|
||||||
|
self.progressBar_3.setProperty("value", 0)
|
||||||
|
self.progressBar_3.setObjectName("progressBar_3")
|
||||||
|
self.label_2 = QtWidgets.QLabel(self.tab_4)
|
||||||
|
self.label_2.setGeometry(QtCore.QRect(140, 110, 131, 21))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.label_2.setFont(font)
|
||||||
|
self.label_2.setObjectName("label_2")
|
||||||
|
self.comboBox_2 = QtWidgets.QComboBox(self.tab_4)
|
||||||
|
self.comboBox_2.setGeometry(QtCore.QRect(320, 110, 211, 26))
|
||||||
|
self.comboBox_2.setObjectName("comboBox_2")
|
||||||
|
self.pushButton_7 = QtWidgets.QPushButton(self.tab_4)
|
||||||
|
self.pushButton_7.setGeometry(QtCore.QRect(270, 240, 201, 32))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.pushButton_7.setFont(font)
|
||||||
|
self.pushButton_7.setObjectName("pushButton_7")
|
||||||
|
self.label_3 = QtWidgets.QLabel(self.tab_4)
|
||||||
|
self.label_3.setGeometry(QtCore.QRect(120, 160, 131, 16))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.label_3.setFont(font)
|
||||||
|
self.label_3.setObjectName("label_3")
|
||||||
|
self.label_4 = QtWidgets.QLabel(self.tab_4)
|
||||||
|
self.label_4.setGeometry(QtCore.QRect(330, 160, 161, 21))
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setFamily("Euphemia UCAS")
|
||||||
|
font.setPointSize(15)
|
||||||
|
self.label_4.setFont(font)
|
||||||
|
self.label_4.setObjectName("label_4")
|
||||||
|
self.lcdNumber = QtWidgets.QLCDNumber(self.tab_4)
|
||||||
|
self.lcdNumber.setGeometry(QtCore.QRect(260, 160, 41, 21))
|
||||||
|
self.lcdNumber.setObjectName("lcdNumber")
|
||||||
|
self.lcdNumber_2 = QtWidgets.QLCDNumber(self.tab_4)
|
||||||
|
self.lcdNumber_2.setGeometry(QtCore.QRect(500, 160, 41, 21))
|
||||||
|
self.lcdNumber_2.setObjectName("lcdNumber_2")
|
||||||
|
self.tabWidget_2.addTab(self.tab_4, "")
|
||||||
|
self.tabWidget.addTab(self.tab_2, "")
|
||||||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||||
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 752, 22))
|
||||||
|
self.menubar.setObjectName("menubar")
|
||||||
|
MainWindow.setMenuBar(self.menubar)
|
||||||
|
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
||||||
|
self.statusbar.setObjectName("statusbar")
|
||||||
|
MainWindow.setStatusBar(self.statusbar)
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
self.tabWidget.setCurrentIndex(0)
|
||||||
|
self.tabWidget_2.setCurrentIndex(0)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
||||||
|
self.pushButton.setText(_translate("MainWindow", "Download"))
|
||||||
|
self.lineEdit.setPlaceholderText(_translate("MainWindow", "Enter download link here"))
|
||||||
|
self.lineEdit_2.setPlaceholderText(_translate("MainWindow", "use browse button to enter save location"))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
|
||||||
|
self.lineEdit_3.setPlaceholderText(_translate("MainWindow", "Enter video URL"))
|
||||||
|
self.lineEdit_4.setPlaceholderText(_translate("MainWindow", "User browse button for save location"))
|
||||||
|
self.pushButton_4.setText(_translate("MainWindow", "Start Download"))
|
||||||
|
self.label.setText(_translate("MainWindow", "Video Quality"))
|
||||||
|
self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("MainWindow", "One Video"))
|
||||||
|
self.lineEdit_5.setPlaceholderText(_translate("MainWindow", "Enter Playlist URL"))
|
||||||
|
self.lineEdit_6.setPlaceholderText(_translate("MainWindow", "Use browse button to enter save location"))
|
||||||
|
self.label_2.setText(_translate("MainWindow", "Video Quality"))
|
||||||
|
self.pushButton_7.setText(_translate("MainWindow", "Start Download"))
|
||||||
|
self.label_3.setText(_translate("MainWindow", "The Current Video :"))
|
||||||
|
self.label_4.setText(_translate("MainWindow", "The Full Playlist Video : "))
|
||||||
|
self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Full Playlist"))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
|
||||||
|
|
||||||
|
import photo_rc
|
@ -0,0 +1,982 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>887</width>
|
||||||
|
<height>456</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/check.png</normaloff>:/icons/check.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>140</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>751</width>
|
||||||
|
<height>431</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab_5">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Page</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>60</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>91</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="photo.qrc">:/icons/home_download.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>141</width>
|
||||||
|
<height>91</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>24</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Download Any Type Of Files</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>380</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>141</width>
|
||||||
|
<height>101</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>24</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Youtube Video Download</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>81</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="photo.qrc">:/icons/youtube.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>60</x>
|
||||||
|
<y>210</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>151</width>
|
||||||
|
<height>91</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>24</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Youtube Playlist Download</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>91</width>
|
||||||
|
<height>101</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="photo.qrc">:/icons/home_youtube.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>380</x>
|
||||||
|
<y>210</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="label_14">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>151</width>
|
||||||
|
<height>101</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>24</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>App Themes & Settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_15">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>81</width>
|
||||||
|
<height>101</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="photo.qrc">:/icons/home_settings.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 1</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>310</x>
|
||||||
|
<y>221</y>
|
||||||
|
<width>131</width>
|
||||||
|
<height>51</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Download</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>130</x>
|
||||||
|
<y>60</y>
|
||||||
|
<width>521</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Enter download link here</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>130</x>
|
||||||
|
<y>100</y>
|
||||||
|
<width>471</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>use browse button to enter save location</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>600</x>
|
||||||
|
<y>100</y>
|
||||||
|
<width>51</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/browse.png</normaloff>:/icons/browse.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>33</width>
|
||||||
|
<height>33</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>130</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>521</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 2</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QTabWidget" name="tabWidget_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>751</width>
|
||||||
|
<height>411</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab_3">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>One Video</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>451</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Enter video URL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_4">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>80</y>
|
||||||
|
<width>451</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>User browse button for save location</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>560</x>
|
||||||
|
<y>80</y>
|
||||||
|
<width>61</width>
|
||||||
|
<height>51</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/browse.png</normaloff>:/icons/browse.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>33</width>
|
||||||
|
<height>33</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QProgressBar" name="progressBar_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>110</x>
|
||||||
|
<y>190</y>
|
||||||
|
<width>511</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_4">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>260</x>
|
||||||
|
<y>290</y>
|
||||||
|
<width>211</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start Download</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>160</x>
|
||||||
|
<y>140</y>
|
||||||
|
<width>131</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Video Quality</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QComboBox" name="comboBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>290</x>
|
||||||
|
<y>140</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_5">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>560</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>61</width>
|
||||||
|
<height>51</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/check.png</normaloff>:/icons/check.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>33</width>
|
||||||
|
<height>33</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>270</x>
|
||||||
|
<y>230</y>
|
||||||
|
<width>191</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_4">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Full Playlist</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_5">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>501</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Enter Playlist URL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_6">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>60</y>
|
||||||
|
<width>451</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Use browse button to enter save location</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_6">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>570</x>
|
||||||
|
<y>60</y>
|
||||||
|
<width>51</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/browse.png</normaloff>:/icons/browse.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>33</width>
|
||||||
|
<height>33</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QProgressBar" name="progressBar_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>220</y>
|
||||||
|
<width>511</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>140</x>
|
||||||
|
<y>110</y>
|
||||||
|
<width>131</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Video Quality</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QComboBox" name="comboBox_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>320</x>
|
||||||
|
<y>110</y>
|
||||||
|
<width>211</width>
|
||||||
|
<height>26</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>1080</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>720</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>480</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>360</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_7">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>260</x>
|
||||||
|
<y>310</y>
|
||||||
|
<width>201</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start Download</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>80</x>
|
||||||
|
<y>170</y>
|
||||||
|
<width>131</width>
|
||||||
|
<height>16</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>The Current Video :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>330</x>
|
||||||
|
<y>170</y>
|
||||||
|
<width>161</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Dosis</family>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>The Full Playlist Video : </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>220</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>101</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>17</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>490</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>141</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>23</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: rgb(0, 0, 0);</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>220</x>
|
||||||
|
<y>260</y>
|
||||||
|
<width>261</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_6">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Page</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QPushButton" name="pushButton_12">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>80</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(50, 50, 50);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_13">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>230</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(50, 50, 50);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_14">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>380</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(25, 35, 45);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>230</x>
|
||||||
|
<y>60</y>
|
||||||
|
<width>321</width>
|
||||||
|
<height>51</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>27</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Choose Your Theme</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_15">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>520</x>
|
||||||
|
<y>160</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>111</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_8">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/home.png</normaloff>:/icons/home.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_9">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>120</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/download.png</normaloff>:/icons/download.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_10">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>300</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/setting.png</normaloff>:/icons/setting.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButton_11">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>210</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="photo.qrc">
|
||||||
|
<normaloff>:/icons/youtube.png</normaloff>:/icons/youtube.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>887</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="photo.qrc"/>
|
||||||
|
<include location="../../../.designer/backup/photo.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE RCC>
|
||||||
|
<RCC version="1.0">
|
||||||
|
<qresource>
|
||||||
|
<file>icons/browse.png</file>
|
||||||
|
<file>icons/check.png</file>
|
||||||
|
<file>icons/home.png</file>
|
||||||
|
<file>icons/youtube.png</file>
|
||||||
|
<file>icons/setting.png</file>
|
||||||
|
<file>icons/download.png</file>
|
||||||
|
<file>icons/home_download.png</file>
|
||||||
|
<file>icons/home_settings.png</file>
|
||||||
|
<file>icons/home_youtube.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,4 @@
|
|||||||
|
https://download.sublimetext.com/Sublime%20Text%20Build%203176.dmg
|
||||||
|
|
||||||
|
|
||||||
|
/Users/macbook/Desktop
|
@ -0,0 +1,519 @@
|
|||||||
|
QToolTip
|
||||||
|
{
|
||||||
|
border: 1px solid black;
|
||||||
|
background-color: #ffa02f;
|
||||||
|
padding: 1px;
|
||||||
|
border-radius: 3px;
|
||||||
|
opacity: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget
|
||||||
|
{
|
||||||
|
color: #b1b1b1;
|
||||||
|
background-color: #323232;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeView, QListView
|
||||||
|
{
|
||||||
|
background-color: silver;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:item:hover
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619);
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:item:selected
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item
|
||||||
|
{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:selected
|
||||||
|
{
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid #ffaa00;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:pressed
|
||||||
|
{
|
||||||
|
background: #444;
|
||||||
|
border: 1px solid #000;
|
||||||
|
background-color: QLinearGradient(
|
||||||
|
x1:0, y1:0,
|
||||||
|
x2:0, y2:1,
|
||||||
|
stop:1 #212121,
|
||||||
|
stop:0.4 #343434/*,
|
||||||
|
stop:0.2 #343434,
|
||||||
|
stop:0.1 #ffaa00*/
|
||||||
|
);
|
||||||
|
margin-bottom:-1px;
|
||||||
|
padding-bottom:1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu
|
||||||
|
{
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item
|
||||||
|
{
|
||||||
|
padding: 2px 20px 2px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item:selected
|
||||||
|
{
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:disabled
|
||||||
|
{
|
||||||
|
color: #808080;
|
||||||
|
background-color: #323232;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractItemView
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4d4d4d, stop: 0.1 #646464, stop: 1 #5d5d5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:focus
|
||||||
|
{
|
||||||
|
/*border: 1px solid darkgray;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4d4d4d, stop: 0 #646464, stop: 1 #5d5d5d);
|
||||||
|
padding: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border: 1px solid #1e1e1e;
|
||||||
|
border-radius: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton
|
||||||
|
{
|
||||||
|
color: #b1b1b1;
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #1e1e1e;
|
||||||
|
border-style: solid;
|
||||||
|
border-radius: 6;
|
||||||
|
padding: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
min-width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:pressed
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox
|
||||||
|
{
|
||||||
|
selection-background-color: #ffaa00;
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
|
||||||
|
border-style: solid;
|
||||||
|
border: 1px solid #1e1e1e;
|
||||||
|
border-radius: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox:hover,QPushButton:hover
|
||||||
|
{
|
||||||
|
border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QComboBox:on
|
||||||
|
{
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-left: 4px;
|
||||||
|
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
|
||||||
|
selection-background-color: #ffaa00;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox QAbstractItemView
|
||||||
|
{
|
||||||
|
border: 2px solid darkgray;
|
||||||
|
selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::drop-down
|
||||||
|
{
|
||||||
|
subcontrol-origin: padding;
|
||||||
|
subcontrol-position: top right;
|
||||||
|
width: 15px;
|
||||||
|
|
||||||
|
border-left-width: 0px;
|
||||||
|
border-left-color: darkgray;
|
||||||
|
border-left-style: solid; /* just a single line */
|
||||||
|
border-top-right-radius: 3px; /* same radius as the QComboBox */
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow
|
||||||
|
{
|
||||||
|
image: url(:/dark_orange/img/down_arrow.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox
|
||||||
|
{
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox:focus
|
||||||
|
{
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit:focus
|
||||||
|
{
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:horizontal {
|
||||||
|
border: 1px solid #222222;
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848);
|
||||||
|
height: 7px;
|
||||||
|
margin: 0px 16px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal
|
||||||
|
{
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f);
|
||||||
|
min-height: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:horizontal {
|
||||||
|
border: 1px solid #1b1b19;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
width: 14px;
|
||||||
|
subcontrol-position: right;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:horizontal {
|
||||||
|
border: 1px solid #1b1b19;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
width: 14px;
|
||||||
|
subcontrol-position: left;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::right-arrow:horizontal, QScrollBar::left-arrow:horizontal
|
||||||
|
{
|
||||||
|
border: 1px solid black;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical
|
||||||
|
{
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848);
|
||||||
|
width: 7px;
|
||||||
|
margin: 16px 0 16px 0;
|
||||||
|
border: 1px solid #222222;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical
|
||||||
|
{
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f);
|
||||||
|
min-height: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical
|
||||||
|
{
|
||||||
|
border: 1px solid #1b1b19;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
|
||||||
|
height: 14px;
|
||||||
|
subcontrol-position: bottom;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:vertical
|
||||||
|
{
|
||||||
|
border: 1px solid #1b1b19;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d7801a, stop: 1 #ffa02f);
|
||||||
|
height: 14px;
|
||||||
|
subcontrol-position: top;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
|
||||||
|
{
|
||||||
|
border: 1px solid black;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit
|
||||||
|
{
|
||||||
|
background-color: #242424;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlainTextEdit
|
||||||
|
{
|
||||||
|
background-color: #242424;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHeaderView::section
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565);
|
||||||
|
color: white;
|
||||||
|
padding-left: 4px;
|
||||||
|
border: 1px solid #6c6c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox:disabled
|
||||||
|
{
|
||||||
|
color: #414141;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::title
|
||||||
|
{
|
||||||
|
text-align: center;
|
||||||
|
spacing: 3px; /* spacing between items in the tool bar */
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::close-button, QDockWidget::float-button
|
||||||
|
{
|
||||||
|
text-align: center;
|
||||||
|
spacing: 1px; /* spacing between items in the tool bar */
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::close-button:hover, QDockWidget::float-button:hover
|
||||||
|
{
|
||||||
|
background: #242424;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::close-button:pressed, QDockWidget::float-button:pressed
|
||||||
|
{
|
||||||
|
padding: 1px -1px -1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMainWindow::separator
|
||||||
|
{
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434);
|
||||||
|
color: white;
|
||||||
|
padding-left: 4px;
|
||||||
|
border: 1px solid #4c4c4c;
|
||||||
|
spacing: 3px; /* spacing between items in the tool bar */
|
||||||
|
}
|
||||||
|
|
||||||
|
QMainWindow::separator:hover
|
||||||
|
{
|
||||||
|
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #d7801a, stop:0.5 #b56c17 stop:1 #ffa02f);
|
||||||
|
color: white;
|
||||||
|
padding-left: 4px;
|
||||||
|
border: 1px solid #6c6c6c;
|
||||||
|
spacing: 3px; /* spacing between items in the tool bar */
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolBar::handle
|
||||||
|
{
|
||||||
|
spacing: 3px; /* spacing between items in the tool bar */
|
||||||
|
background: url(:/dark_orange/img/handle.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::separator
|
||||||
|
{
|
||||||
|
height: 2px;
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434);
|
||||||
|
color: white;
|
||||||
|
padding-left: 4px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QProgressBar
|
||||||
|
{
|
||||||
|
border: 2px solid grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QProgressBar::chunk
|
||||||
|
{
|
||||||
|
background-color: #d7801a;
|
||||||
|
width: 2.15px;
|
||||||
|
margin: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
color: #b1b1b1;
|
||||||
|
border: 1px solid #444;
|
||||||
|
border-bottom-style: none;
|
||||||
|
background-color: #323232;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
margin-right: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::pane {
|
||||||
|
border: 1px solid #444;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:last
|
||||||
|
{
|
||||||
|
margin-right: 0; /* the last selected tab has nothing to overlap with on the right */
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:first:!selected
|
||||||
|
{
|
||||||
|
margin-left: 0px; /* the last selected tab has nothing to overlap with on the right */
|
||||||
|
|
||||||
|
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:!selected
|
||||||
|
{
|
||||||
|
color: #b1b1b1;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
margin-top: 3px;
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:.4 #343434);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected
|
||||||
|
{
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:!selected:hover
|
||||||
|
{
|
||||||
|
/*border-top: 2px solid #ffaa00;
|
||||||
|
padding-bottom: 3px;*/
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:0.4 #343434, stop:0.2 #343434, stop:0.1 #ffaa00);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:checked, QRadioButton::indicator:unchecked{
|
||||||
|
color: #b1b1b1;
|
||||||
|
background-color: #323232;
|
||||||
|
border: 1px solid #b1b1b1;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:checked
|
||||||
|
{
|
||||||
|
background-color: qradialgradient(
|
||||||
|
cx: 0.5, cy: 0.5,
|
||||||
|
fx: 0.5, fy: 0.5,
|
||||||
|
radius: 1.0,
|
||||||
|
stop: 0.25 #ffaa00,
|
||||||
|
stop: 0.3 #323232
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox::indicator{
|
||||||
|
color: #b1b1b1;
|
||||||
|
background-color: #323232;
|
||||||
|
border: 1px solid #b1b1b1;
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator
|
||||||
|
{
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:hover, QCheckBox::indicator:hover
|
||||||
|
{
|
||||||
|
border: 1px solid #ffaa00;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox::indicator:checked
|
||||||
|
{
|
||||||
|
image:url(:/dark_orange/img/checkbox.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox::indicator:disabled, QRadioButton::indicator:disabled
|
||||||
|
{
|
||||||
|
border: 1px solid #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QSlider::groove:horizontal {
|
||||||
|
border: 1px solid #3A3939;
|
||||||
|
height: 8px;
|
||||||
|
background: #201F1F;
|
||||||
|
margin: 2px 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSlider::handle:horizontal {
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,
|
||||||
|
stop: 0.0 silver, stop: 0.2 #a8a8a8, stop: 1 #727272);
|
||||||
|
border: 1px solid #3A3939;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin: -4px 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSlider::groove:vertical {
|
||||||
|
border: 1px solid #3A3939;
|
||||||
|
width: 8px;
|
||||||
|
background: #201F1F;
|
||||||
|
margin: 0 0px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSlider::handle:vertical {
|
||||||
|
background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 silver,
|
||||||
|
stop: 0.2 #a8a8a8, stop: 1 #727272);
|
||||||
|
border: 1px solid #3A3939;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin: 0 -4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSpinBox {
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|