def __initProxyTab__(self): self._enableProxyCheck = CheckBox('') self._proxyHostEdit = LineEdit() self._proxyPortEdit = LineEdit() self._proxyUserEdit = LineEdit() self._proxyPwdEdit = LineEdit() grid = QGridLayout() grid.setSpacing(8) grid.setRowStretch(0, 1) grid.addWidget(Label("HttpProxy"), 1, 0) grid.addWidget(self._enableProxyCheck, 1, 1) grid.addWidget(Label("Host"), 2, 0) grid.addWidget(self._proxyHostEdit, 2, 1) grid.addWidget(Label("Port"), 3, 0) grid.addWidget(self._proxyPortEdit, 3, 1) grid.addWidget(Label("UserName"), 4, 0) grid.addWidget(self._proxyUserEdit, 4, 1) grid.addWidget(Label("Password"), 5, 0) grid.addWidget(self._proxyPwdEdit, 5, 1) grid.setRowStretch(6, 1) widget = QWidget() widget.setLayout(grid) return widget
def __addPicItem__(self, rowIdx: int, colIdx: int, url: QUrl): icon = Label('', LabelStyle.Icon) icon.setAlignment(Qt.AlignCenter) self.setCellWidget(rowIdx, colIdx, icon) reply = self._netManager.get(QNetworkRequest(url)) reply.finished.connect(lambda: self.__picDownload__(rowIdx, colIdx))
def __initHead__(self): self._searchEdit = LineEdit(iconUrl=getResourcePath() + "/svg/search2.svg") self._searchErrLabel = Label('', LabelStyle.SearchErr) self._searchErrLabel.hide() layout = QVBoxLayout() layout.addWidget(self._searchEdit) layout.addWidget(self._searchErrLabel) layout.setContentsMargins(0, 0, 0, 5) return layout
def __initHead__(self): self._btnRetry = PushButton('', ButtonStyle.TaskRetry) self._btnCancel = PushButton('', ButtonStyle.TaskCancel) self._btnDelete = PushButton('', ButtonStyle.TaskDelete) self._btnOpen = PushButton('', ButtonStyle.TaskOpen) self._btnExpand = PushButton('', ButtonStyle.TaskExpand) self._btnExpand.clicked.connect(self.__expandClick__) btnLayout = createHBoxLayout([ self._btnRetry, self._btnCancel, #self._btnDelete, self._btnOpen, self._btnExpand ]) self._titleLabel = Label('', LabelStyle.PageTitle) self._descLabel = Label() self._errLabel = Label() self._errLabel.hide() labelLayout = createVBoxLayout( [self._titleLabel, self._descLabel, self._errLabel]) labelLayout.insertStretch(0, 1) labelLayout.addStretch(1) self._picLabel = Label('', LabelStyle.Icon) self._picLabel.setMinimumHeight(64) headLayout = QHBoxLayout() headLayout.addWidget(self._picLabel) headLayout.addLayout(labelLayout) headLayout.addStretch(1) headLayout.addLayout(btnLayout) return headLayout
class AboutView(QWidget): def __init__(self): super(AboutView, self).__init__() self.__initView__() def __initView__(self): grid = QGridLayout(self) grid.addWidget(self.__initLogo__(), 0, 0, Qt.AlignLeft) grid.addLayout(self.__initContent__(), 0, 1) def __initLogo__(self): path = getResourcePath() + "/svg/V.svg" self._logo = QLabel() self._logo.setPixmap(QPixmap(path)) return self._logo def __initButton__(self): path = getResourcePath() + "/svg/" self._feedbackBtn = PushButton('Feedback', ButtonStyle.Default, iconUrl=path + 'github.svg') self._buymeacoffeeBtn = PushButton('Buymeacoffee', ButtonStyle.Info, iconUrl=path + 'buymeacoffee.svg') self._paypalBtn = PushButton('Paypal', ButtonStyle.Primary, iconUrl=path + 'paypal.svg') layout = QHBoxLayout() layout.addWidget(self._feedbackBtn) layout.addWidget(self._buymeacoffeeBtn) layout.addWidget(self._paypalBtn) return layout def __initContent__(self): self._titleLabel = Label('', LabelStyle.HugeTitle) self._authorLabel = Label('') self._versionLabel = Label('') self._lastVersionLabel = Label('') layout = QVBoxLayout() layout.addWidget(self._titleLabel) layout.addWidget(self._authorLabel) layout.addWidget(self._versionLabel) layout.addWidget(self._lastVersionLabel) layout.addLayout(self.__initButton__()) return layout def setTitle(self, text: str): self._titleLabel.setText(text) def setAuthor(self, text: str): self._authorLabel.setText('MADE WITH ♥ BY ' + text) def setVersion(self, text: str): self._versionLabel.setText('VERSION ' + text) def setLastVersion(self, text: str): self._lastVersionLabel.setText('LAST-VERSION ' + text)
def __initContent__(self): self._titleLabel = Label('', LabelStyle.HugeTitle) self._authorLabel = Label('') self._versionLabel = Label('') self._lastVersionLabel = Label('') layout = QVBoxLayout() layout.addWidget(self._titleLabel) layout.addWidget(self._authorLabel) layout.addWidget(self._versionLabel) layout.addWidget(self._lastVersionLabel) layout.addLayout(self.__initButton__()) return layout
def __createContent__(self, typeStr: str): layout = QGridLayout() layout.setContentsMargins(0, 0, 10, 10) layout.setSpacing(10) layout.addWidget(Label(typeStr, LabelStyle.PageSubTitle), 0, 0, Qt.AlignTop) layout.addWidget(Line('H'), 1, 0, Qt.AlignTop) layout.addWidget(self._listMap[typeStr], 2, 0) self._pageMap[typeStr].setLayout(layout) self._pageMap[typeStr].hide() return self._pageMap[typeStr]
def __initIconWidget__(self): self._icon = Label('') self._icon.setStyleSheet("QLabel{background-color:rgb(0,0,0);}") self._icon.setPixmap(QPixmap(getResourcePath() + "/svg/V.svg")) self._icon.setAlignment(Qt.AlignCenter) self._iconLabel = Label('', LabelStyle.LogoBottom) self._iconLabel.setAlignment(Qt.AlignCenter) self._iconLabel.hide() layout = QVBoxLayout() layout.setSpacing(15) layout.setContentsMargins(0, 0, 0, 0) layout.addStretch(1) layout.addWidget(self._icon) layout.addWidget(self._iconLabel) layout.addStretch(1) widget = QWidget() widget.setStyleSheet("QWidget{background-color:rgb(0,0,0);}") widget.setLayout(layout) return widget
def __initTail__(self): self._trackQualityComboBox = ComboBox([], 150) self._videoQualityComboBox = ComboBox([], 150) self._prePageBtn = PushButton('', ButtonStyle.PrePage) self._nextPageBtn = PushButton('', ButtonStyle.NextPage) self._pageIndexEdit = LineEdit('') self._pageIndexEdit.setAlignment(Qt.AlignCenter) self._pageIndexEdit.setEnabled(False) self._downloadBtn = PushButton('Download', ButtonStyle.Primary) layout = QHBoxLayout() layout.addWidget(Label('Track:')) layout.addWidget(self._trackQualityComboBox) layout.addWidget(Label('Video:')) layout.addWidget(self._videoQualityComboBox) layout.addStretch(1) layout.addWidget(self._prePageBtn) layout.addWidget(self._pageIndexEdit) layout.addWidget(self._nextPageBtn) layout.addWidget(self._downloadBtn) return layout
def __initAccountTab__(self): self._deviceCodeEdit = LineEdit() self._confirmBtn = PushButton("LOGIN", ButtonStyle.Primary) grid = QGridLayout() grid.setSpacing(15) grid.setRowStretch(0, 1) grid.addLayout( createHBoxLayout([Label("DeviceCode"), self._deviceCodeEdit]), 1, 0, 1, 2) grid.setRowStretch(3, 1) grid.addWidget(self._confirmBtn, 5, 0, 1, 2) grid.setRowStretch(6, 1) widget = QWidget() widget.setLayout(grid) return widget
def __initLefTab__(self): self._listTab = ListWidget(ListWidgetStyle.TaskTab) self._listTab.setIconSize(QSize(20, 20)) iconPath = getResourcePath() + "/svg/taskTab/" self._listTab.addIConTextItem(iconPath + 'download.svg', TaskStatus.Download.name) self._listTab.addIConTextItem(iconPath + 'complete.svg', TaskStatus.Complete.name) self._listTab.addIConTextItem(iconPath + 'error.svg', TaskStatus.Error.name) self._listTab.itemClicked.connect(self.__tabItemChanged__) layout = QGridLayout() layout.addWidget(Label("TASK LIST", LabelStyle.PageTitle), 0, 0, Qt.AlignLeft) layout.addWidget(self._listTab, 1, 0, Qt.AlignLeft) layout.addWidget(Line('V'), 0, 1, 2, 1, Qt.AlignLeft) return layout
class LoginView(FramelessWidget): viewWidth = 650 viewHeight = 400 logoWidth = 300 def __init__(self): super(LoginView, self).__init__() self.setFixedSize(self.viewWidth, self.viewHeight) self.__initView__() self.setWindowButton(True, False, False) def __initAccountTab__(self): self._deviceCodeEdit = LineEdit() self._confirmBtn = PushButton("LOGIN", ButtonStyle.Primary) grid = QGridLayout() grid.setSpacing(15) grid.setRowStretch(0, 1) grid.addLayout( createHBoxLayout([Label("DeviceCode"), self._deviceCodeEdit]), 1, 0, 1, 2) grid.setRowStretch(3, 1) grid.addWidget(self._confirmBtn, 5, 0, 1, 2) grid.setRowStretch(6, 1) widget = QWidget() widget.setLayout(grid) return widget def __initProxyTab__(self): self._enableProxyCheck = CheckBox('') self._proxyHostEdit = LineEdit() self._proxyPortEdit = LineEdit() self._proxyUserEdit = LineEdit() self._proxyPwdEdit = LineEdit() grid = QGridLayout() grid.setSpacing(8) grid.setRowStretch(0, 1) grid.addWidget(Label("HttpProxy"), 1, 0) grid.addWidget(self._enableProxyCheck, 1, 1) grid.addWidget(Label("Host"), 2, 0) grid.addWidget(self._proxyHostEdit, 2, 1) grid.addWidget(Label("Port"), 3, 0) grid.addWidget(self._proxyPortEdit, 3, 1) grid.addWidget(Label("UserName"), 4, 0) grid.addWidget(self._proxyUserEdit, 4, 1) grid.addWidget(Label("Password"), 5, 0) grid.addWidget(self._proxyPwdEdit, 5, 1) grid.setRowStretch(6, 1) widget = QWidget() widget.setLayout(grid) return widget def __initIconWidget__(self): self._icon = Label('') self._icon.setStyleSheet("QLabel{background-color:rgb(0,0,0);}") self._icon.setPixmap(QPixmap(getResourcePath() + "/svg/V.svg")) self._icon.setAlignment(Qt.AlignCenter) self._iconLabel = Label('', LabelStyle.LogoBottom) self._iconLabel.setAlignment(Qt.AlignCenter) self._iconLabel.hide() layout = QVBoxLayout() layout.setSpacing(15) layout.setContentsMargins(0, 0, 0, 0) layout.addStretch(1) layout.addWidget(self._icon) layout.addWidget(self._iconLabel) layout.addStretch(1) widget = QWidget() widget.setStyleSheet("QWidget{background-color:rgb(0,0,0);}") widget.setLayout(layout) return widget def __initView__(self): iconWidget = self.__initIconWidget__() self._tab = QTabWidget(self) self._tab.addTab(self.__initAccountTab__(), "LOGIN") self._tab.addTab(self.__initProxyTab__(), "PROXY") self._tab.setFixedWidth(self.viewWidth - self.logoWidth - 60) self._tab.hide() grid = self.getGrid() grid.setSpacing(15) grid.setContentsMargins(0, 0, 0, 0) grid.addWidget(iconWidget) grid.addWidget(self._tab, 0, 1, Qt.AlignCenter) self.setValidMoveWidget(iconWidget) def showEnterView(self): self._tab.show() def hideEnterView(self): self._tab.hide() def setDeviceCode(self, text): self._deviceCodeEdit.setText(text) def enableHttpProxy(self) -> bool: return self._enableProxyCheck.isChecked() def getProxyInfo(self) -> dict: infos = { 'host': self._proxyHostEdit.text(), 'port': self._proxyPortEdit.text(), 'username': self._proxyUserEdit.text(), 'password': self._proxyPwdEdit.text() } return infos def connectConfirmButton(self, func): self._confirmBtn.clicked.connect(func) def enableConfirmButton(self, enable): self._confirmBtn.setEnabled(enable) def setMsg(self, text): if len(text) <= 0: self._iconLabel.hide() else: self._iconLabel.setText(text) self._iconLabel.show() def showErrMessage(self, text: str): qmb = QMessageBox(self) qmb.setWindowTitle('Error') qmb.setIcon(QMessageBox.Warning) qmb.setText(text) qmb.addButton(QPushButton('OK', qmb), QMessageBox.YesRole) qmb.open()
class TaskItemView(QWidget): def __init__(self): super().__init__() self.__initView__() self.setObjectName('TaskItemView') self.setAttribute(Qt.WA_StyledBackground) def __initView__(self): layout = QVBoxLayout() layout.addLayout(self.__initHead__(), Qt.AlignTop) layout.addWidget(self.__initList__()) self.setLayout(layout) def __initHead__(self): self._btnRetry = PushButton('', ButtonStyle.TaskRetry) self._btnCancel = PushButton('', ButtonStyle.TaskCancel) self._btnDelete = PushButton('', ButtonStyle.TaskDelete) self._btnOpen = PushButton('', ButtonStyle.TaskOpen) self._btnExpand = PushButton('', ButtonStyle.TaskExpand) self._btnExpand.clicked.connect(self.__expandClick__) btnLayout = createHBoxLayout([ self._btnRetry, self._btnCancel, #self._btnDelete, self._btnOpen, self._btnExpand ]) self._titleLabel = Label('', LabelStyle.PageTitle) self._descLabel = Label() self._errLabel = Label() self._errLabel.hide() labelLayout = createVBoxLayout( [self._titleLabel, self._descLabel, self._errLabel]) labelLayout.insertStretch(0, 1) labelLayout.addStretch(1) self._picLabel = Label('', LabelStyle.Icon) self._picLabel.setMinimumHeight(64) headLayout = QHBoxLayout() headLayout.addWidget(self._picLabel) headLayout.addLayout(labelLayout) headLayout.addStretch(1) headLayout.addLayout(btnLayout) return headLayout def __initList__(self): self._list = QWidget() self._list.setObjectName("DownloadItemsWidget") self._listLayout = QVBoxLayout(self._list) self._listLayout.setSpacing(0) return self._list def setLabel(self, title, desc): self._titleLabel.setText(title) self._descLabel.setText(desc) def setErrmsg(self, msg): self._errLabel.setText(msg) def setPic(self, data): pic = QPixmap() pic.loadFromData(data) self._picLabel.setPixmap(pic.scaled(64, 64)) def addListItem(self, view): self._listLayout.addWidget(view) def __expandClick__(self): if self._list.isHidden(): self._list.setVisible(True) else: self._list.setVisible(False) def connectButton(self, name: str, func): if name == 'retry': self._btnRetry.clicked.connect(func) elif name == 'cancel': self._btnCancel.clicked.connect(func) elif name == 'delete': self._btnDelete.clicked.connect(func) elif name == 'open': self._btnOpen.clicked.connect(func)
class SearchView(QWidget): def __init__(self): super(SearchView, self).__init__() self._rowCount = 20 self._table = {} self._lock = threading.Lock() self.__initView__() self._searchEdit.setFocus() def __initView__(self): grid = QVBoxLayout(self) grid.addLayout(self.__initHead__(), Qt.AlignTop) grid.addLayout(self.__initContent__()) grid.addLayout(self.__initTail__(), Qt.AlignBottom) def __initHead__(self): self._searchEdit = LineEdit(iconUrl=getResourcePath() + "/svg/search2.svg") self._searchErrLabel = Label('', LabelStyle.SearchErr) self._searchErrLabel.hide() layout = QVBoxLayout() layout.addWidget(self._searchEdit) layout.addWidget(self._searchErrLabel) layout.setContentsMargins(0, 0, 0, 5) return layout def __initTail__(self): self._trackQualityComboBox = ComboBox([], 150) self._videoQualityComboBox = ComboBox([], 150) self._prePageBtn = PushButton('', ButtonStyle.PrePage) self._nextPageBtn = PushButton('', ButtonStyle.NextPage) self._pageIndexEdit = LineEdit('') self._pageIndexEdit.setAlignment(Qt.AlignCenter) self._pageIndexEdit.setEnabled(False) self._downloadBtn = PushButton('Download', ButtonStyle.Primary) layout = QHBoxLayout() layout.addWidget(Label('Track:')) layout.addWidget(self._trackQualityComboBox) layout.addWidget(Label('Video:')) layout.addWidget(self._videoQualityComboBox) layout.addStretch(1) layout.addWidget(self._prePageBtn) layout.addWidget(self._pageIndexEdit) layout.addWidget(self._nextPageBtn) layout.addWidget(self._downloadBtn) return layout def __initContent__(self): self._tabWidget = QTabWidget(self) self._tabWidget.addTab(self.__initTable__(Type.Album), "ALBUM") self._tabWidget.addTab(self.__initTable__(Type.Track), "TRACK") self._tabWidget.addTab(self.__initTable__(Type.Video), "VIDEO") self._tabWidget.addTab(self.__initTable__(Type.Playlist), "PLAYLIST") layout = QVBoxLayout() layout.addWidget(self._tabWidget) return layout def __initTable__(self, stype: Type): columnHeads = [] columnWidths = [] if stype == Type.Album: columnHeads = [ '#', ' ', ' ', 'Title', 'Artists', 'Release', 'Duration' ] columnWidths = [50, 60, 60, 400, 200, 200] elif stype == Type.Track: columnHeads = ['#', ' ', 'Title', 'Album', 'Artists', 'Duration'] columnWidths = [50, 60, 400, 200, 200] elif stype == Type.Video: columnHeads = ['#', ' ', ' ', 'Title', 'Artists', 'Duration'] columnWidths = [50, 60, 60, 400, 200, 200] elif stype == Type.Playlist: columnHeads = ['#', ' ', 'Title', 'Artist', 'Duration'] columnWidths = [50, 60, 400, 200, 200] self._table[stype] = TableWidget(columnHeads, self._rowCount) for index, width in enumerate(columnWidths): self._table[stype].setColumnWidth(index, width) return self._table[stype] def __clearTableRowItems__(self, stype: Type, fromIndex: int): endIndex = self._rowCount - 1 columnNum = self._table[stype].columnCount() while fromIndex <= endIndex: for colIdx in range(0, columnNum): self._table[stype].addItem(fromIndex, colIdx, '') fromIndex += 1 def setTableItems(self, stype: Type, indexOffset: int, result: tidal_dl.model.SearchResult): if stype == Type.Album: items = result.albums.items datas = [] for index, item in enumerate(items): rowData = [ str(index + 1 + indexOffset), QUrl(API.getCoverUrl(item.cover)), API.getFlag(item, Type.Album, True), item.title, item.artists[0].name, str(item.releaseDate), getDurationString(item.duration) ] datas.append(rowData) elif stype == Type.Track: items = result.tracks.items datas = [] for index, item in enumerate(items): rowData = [ str(index + 1 + indexOffset), API.getFlag(item, Type.Track, True), item.title, item.album.title, item.artists[0].name, getDurationString(item.duration) ] datas.append(rowData) elif stype == Type.Video: items = result.videos.items datas = [] for index, item in enumerate(items): rowData = [ str(index + 1 + indexOffset), QUrl(API.getCoverUrl(item.imageID)), API.getFlag(item, Type.Video, True), item.title, item.artists[0].name, getDurationString(item.duration) ] datas.append(rowData) elif stype == Type.Playlist: items = result.playlists.items datas = [] for index, item in enumerate(items): rowData = [ str(index + 1 + indexOffset), QUrl(API.getCoverUrl(item.squareImage)), item.title, '', getDurationString(item.duration) ] datas.append(rowData) for index, rowData in enumerate(datas): for colIdx, obj in enumerate(rowData): self._table[stype].addItem(index, colIdx, obj) self.__clearTableRowItems__(stype, len(items)) self._table[stype].viewport().update() def getSearchText(self): return self._searchEdit.text() def setSearchErrmsg(self, text: str): self._searchErrLabel.setText(text) if text != '': self._searchErrLabel.show() else: self._searchErrLabel.hide() def setPageIndex(self, index, sum): self._pageIndexEdit.setText(str(index) + '/' + str(sum)) def getPageIndex(self) -> (int, int): nums = self._pageIndexEdit.text().split('/') return int(nums[0]), int(nums[1]) def getSelectedTabIndex(self): return self._tabWidget.currentIndex() def getSelectedTableIndex(self, stype: Type): array = self._table[stype].selectedIndexes() if len(array) <= 0: return -1 return array[0].row() def setTrackQualityItems(self, items: list, curItem=None): self._trackQualityComboBox.setItems(items) if curItem is not None: self._trackQualityComboBox.setCurrentText(curItem) def setVideoQualityItems(self, items: list, curItem=None): self._videoQualityComboBox.setItems(items) if curItem is not None: self._videoQualityComboBox.setCurrentText(curItem) def getTrackQualityText(self): return self._trackQualityComboBox.currentText() def getVideoQualityText(self): return self._videoQualityComboBox.currentText() def connectButton(self, name: str, func): if name == 'search': self._searchEdit.returnPressed.connect(func) elif name == 'prePage': self._prePageBtn.clicked.connect(func) elif name == 'nextPage': self._nextPageBtn.clicked.connect(func) elif name == 'download': self._downloadBtn.clicked.connect(func) def connectTab(self, func): self._tabWidget.currentChanged.connect(func) def connectQualityComboBox(self, name: str, func): if name == 'track': self._trackQualityComboBox.currentIndexChanged.connect(func) else: self._videoQualityComboBox.currentIndexChanged.connect(func)
def __initView__(self): self._indexLabel = Label('1') self._codecLabel = Label('', LabelStyle.Tag) self._titleLabel = Label('title', LabelStyle.Bold) self._ownLabel = Label('own', LabelStyle.Italic) self._ownLabel.setMaximumWidth(200) self._actionLabel = Label('', LabelStyle.Italic) self._actionLabel.setFixedWidth(80) self._errLabel = Label('') self._errLabel.setVisible(False) self._sizeLabel = Label('/') self._speedLabel = Label('') self._progress = QProgressBar() self._progress.setTextVisible(False) self._progress.setFixedHeight(3) self._progress.setFixedWidth(300) self._progress.setRange(0, 100) titleLayout = QHBoxLayout() titleLayout.setSpacing(3) titleLayout.setContentsMargins(0, 0, 0, 0) titleLayout.addWidget(self._indexLabel, Qt.AlignLeft) titleLayout.addWidget(self._titleLabel, Qt.AlignLeft) titleLayout.addStretch(50) titleLayout.addWidget(self._codecLabel, Qt.AlignRight) titleLayout.addWidget(self._ownLabel, Qt.AlignRight) speedLayout = QHBoxLayout() speedLayout.setSpacing(30) speedLayout.addWidget(self._sizeLabel) speedLayout.addWidget(self._speedLabel) grid = QGridLayout(self) grid.setContentsMargins(0,0,0,0) grid.setSpacing(2) grid.addLayout(titleLayout, 0, 0, Qt.AlignLeft | Qt.AlignVCenter) grid.addWidget(self._progress, 0, 1, Qt.AlignRight | Qt.AlignVCenter) grid.addWidget(self._actionLabel, 0, 2, Qt.AlignRight | Qt.AlignVCenter) grid.addWidget(self._errLabel, 1, 0, Qt.AlignLeft | Qt.AlignVCenter) grid.addLayout(speedLayout, 1, 1, Qt.AlignLeft | Qt.AlignVCenter)
class DownloadItemView(QWidget): def __init__(self): super(DownloadItemView, self).__init__() self.__initView__() self.setObjectName('DownloadItemView') self.setAttribute(Qt.WA_StyledBackground) def __initView__(self): self._indexLabel = Label('1') self._codecLabel = Label('', LabelStyle.Tag) self._titleLabel = Label('title', LabelStyle.Bold) self._ownLabel = Label('own', LabelStyle.Italic) self._ownLabel.setMaximumWidth(200) self._actionLabel = Label('', LabelStyle.Italic) self._actionLabel.setFixedWidth(80) self._errLabel = Label('') self._errLabel.setVisible(False) self._sizeLabel = Label('/') self._speedLabel = Label('') self._progress = QProgressBar() self._progress.setTextVisible(False) self._progress.setFixedHeight(3) self._progress.setFixedWidth(300) self._progress.setRange(0, 100) titleLayout = QHBoxLayout() titleLayout.setSpacing(3) titleLayout.setContentsMargins(0, 0, 0, 0) titleLayout.addWidget(self._indexLabel, Qt.AlignLeft) titleLayout.addWidget(self._titleLabel, Qt.AlignLeft) titleLayout.addStretch(50) titleLayout.addWidget(self._codecLabel, Qt.AlignRight) titleLayout.addWidget(self._ownLabel, Qt.AlignRight) speedLayout = QHBoxLayout() speedLayout.setSpacing(30) speedLayout.addWidget(self._sizeLabel) speedLayout.addWidget(self._speedLabel) grid = QGridLayout(self) grid.setContentsMargins(0,0,0,0) grid.setSpacing(2) grid.addLayout(titleLayout, 0, 0, Qt.AlignLeft | Qt.AlignVCenter) grid.addWidget(self._progress, 0, 1, Qt.AlignRight | Qt.AlignVCenter) grid.addWidget(self._actionLabel, 0, 2, Qt.AlignRight | Qt.AlignVCenter) grid.addWidget(self._errLabel, 1, 0, Qt.AlignLeft | Qt.AlignVCenter) grid.addLayout(speedLayout, 1, 1, Qt.AlignLeft | Qt.AlignVCenter) def setLabel(self, index, title, own): self._indexLabel.setText(str(index)) self._titleLabel.setText(title) self._ownLabel.setText(own) def setErrmsg(self, msg): self._errLabel.setText(msg) self._errLabel.setVisible(len(msg) > 0) def setAction(self, msg): self._actionLabel.setText(msg) def setProgress(self, value): self._progress.setValue(value) pass def setSize(self, curSize: str, totalSize: str): self._sizeLabel.setText(f'{curSize} / {totalSize}') def setSpeed(self, speed: str): self._speedLabel.setText(speed) def setCodec(self, codec: str): self._codecLabel.setText(codec)