2017-08-17 314 views
0

我目前被卡住了。我正在努力讓自己的QTextBrowser能夠從程序輸出中精確地呈現文本輸入(多個部分)。但下載進度變成幾行文字,因爲我無法實現處理回車的方法。下面是獲得真實追加到我QTextBrowser,其中\r\n顯示的字符串:PyQt5中的QTextBrowser回車

dQw4w9WgXcQ:下載縮略圖... \ n

dQw4w9WgXcQ:寫入縮略圖:d:\ Musikk \ DL的\裏克阿斯特利 - 從未去放棄你Up.jpg \ n

目的地:d:\ Musikk \ DL的\理查德·艾斯利 - 決不會給你Up.webm \ n

\ r 3.33MiB的0.9%,4.03MiB/s ETA 00:00

\ r在3.62MiB/s的ETA 00:00

而且最後兩行3.33MiB的1.8%,會有很多的,因爲它會下載它和一些文件中的所有100% 。

我目前的實施是簡單的(不處理這個問題),與

self.textBrowser.append(text) 

而且你會得到這樣的結果(它的所有片段):

dQw4w9WgXcQ:下載縮略圖...

dQw4w9WgXcQ:寫入縮略圖:d:\ Musikk \ DL的\理查德·艾斯利 - 決不會給你Up.jpg

目的地:d:\ Musikk \ DL的\理查德·艾斯利 - 決不會給你Up.webm

3.33MiB的

0.0%的19.15KiB/s的ETA 02:58 3.33MiB的

0.1%,至57.44KiB/s的ETA 0時59

0.2在131.57KiB/s的ETA 3.33MiB的%0時25

我還可以除去在字符串\n具有其中那些是線之間的更小的空間當下。

我嘗試了另一個部分解決方案,當字符串包含\r而不是追加,但是,某些字符串包含幾個\r字符,並且這不解釋。

 self.textbrowser.insertPlainText(text) 
     if '\r' in text: 
      self.textbrowser.moveCursor(QTextCursor.End, mode=QTextCursor.MoveAnchor) 
      self.textbrowser.moveCursor(QTextCursor.StartOfLine, mode=QTextCursor.MoveAnchor) 
      self.textbrowser.moveCursor(QTextCursor.End,mode=QTextCursor.KeepAnchor) 
      self.textbrowser.textCursor().removeSelectedText() 
      self.textbrowser.textCursor().deletePreviousChar() 

我也試過:

 self.textbrowser.append(text) 
     self.textbrowser.textCursor().deletePreviousChar() 

,但是去除了線之間的一些空間(刪除換行符.append()補充道。)但是它仍然沒有做任何事情,但刪除\ r字符就好像它不在那裏一樣。我根本無法獲得一致的解決方案。

作爲參考,這是一個youtube-dl.exe包裝。如果你使用youtube-dl。exe(例如Windows 10上的Powershell),它會做正確的事情,並在更新百分比時跳到行首,所以你會得到一個很好的下載行,它會自行增加,並且ETA會倒計時也是如此,而不會在很多方面發展。

對於簡化代碼,下面是一個示例,顯示它正在使用中,除了附加解碼的字符串之外沒有其他解決方案。請注意,這是前段時間的SO回答,其中有QTextEdit而不是QTextBrowser。它需要youtube-dl.exe位於python腳本的工作目錄中。在這種情況下,QTextEdit被稱爲self.edit

import sys 

from PyQt5.QtCore import QProcess 
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QTextEdit, QLabel, QLineEdit 


class GUI(QProcess): 
    def __init__(self, parent=None): 
     super(GUI, self).__init__(parent=parent) 

     # Create an instance variable here (of type QTextEdit) 
     self.startBtn = QPushButton('OK') 
     self.stopBtn = QPushButton('Cancel') 

     self.hbox = QHBoxLayout() 
     self.hbox.addStretch(1) 
     self.hbox.addWidget(self.startBtn) 
     self.hbox.addWidget(self.stopBtn) 

     self.label = QLabel("Url: ") 
     self.lineEdit = QLineEdit() 

     self.lineEdit.textChanged.connect(self.EnableStart) 

     self.hbox2 = QHBoxLayout() 
     self.hbox2.addWidget(self.label) 
     self.hbox2.addWidget(self.lineEdit) 

     self.edit = QTextEdit() 
     self.edit.setWindowTitle("QTextEdit Standard Output Redirection") 

     self.vbox = QVBoxLayout() 
     self.vbox.addStretch(1) 

     self.vbox.addLayout(self.hbox2) 
     self.vbox.addWidget(self.edit) 
     self.vbox.addLayout(self.hbox) 

     self.central = QWidget() 

     self.central.setLayout(self.vbox) 
     self.central.show() 

     self.startBtn.clicked.connect(self.startDownload) 
     self.stopBtn.clicked.connect(self.kill) 
     self.stateChanged.connect(self.slotChanged) 

     self.EnableStart() 

    def slotChanged(self, newState): 
     if newState == QProcess.NotRunning: 
      self.startBtn.setDisabled(False) 
     elif newState == QProcess.Running: 
      self.startBtn.setDisabled(True) 

    def startDownload(self): 
     self.start("youtube-dl", [self.lineEdit.text()]) 

    def readStdOutput(self): 
     self.edit.append(str(self.readAllStandardOutput().data().decode('utf-8','ignore'))) 

    def EnableStart(self): 
     self.startBtn.setDisabled(self.lineEdit.text() == "") 


def main(): 
    app = QApplication(sys.argv) 
    qProcess = GUI() 

    qProcess.setProcessChannelMode(QProcess.MergedChannels) 
    qProcess.readyReadStandardOutput.connect(qProcess.readStdOutput) 

    return app.exec_() 


if __name__ == '__main__': 
    main() 

我真的不知道這是可行的,但總括起來:

  • 附加到的QTextEdit的字符串不包含換行符,有時回車符。 (分別爲\n\r

  • 這些字符串需要在沒有新行的情況下添加,可能與追加後刪除最後換行符一樣簡單。

  • 有幾次,句子被髮送到一大堆,所以我的第二個實現不起作用。請注意下面的注意事項,注意輸出是二進制的,因爲在這種情況下它還沒有被轉換爲字符串。打印下面的解碼流會給你在控制檯中的預期行爲。 (但在的QTextEdit不是很明顯)

b'[youtube] dQw4w9WgXcQ: Downloading webpage\n[youtube] dQw4w9WgXcQ: Downloading video info webpage\n[youtube] dQw4w9WgXcQ: Extracting video information\n[youtube] dQw4w9WgXcQ: Downloading MPD manifest\n[youtube] dQw4w9WgXcQ: Downloading thumbnail ...\n' 

b'[youtube] dQw4w9WgXcQ: Writing thumbnail to: D:\\Musikk\\DLs\\Rick Astley - Never Gonna Give You Up.jpg\n' 

b'[download] Destination: D:\\Musikk\\DLs\\Rick Astley - Never Gonna Give You Up.webm\n' 

b'\r[download] 0.0% of 3.33MiB at 332.99KiB/s ETA 00:10\r[download] 0.1% of 3.33MiB at 856.39KiB/s ETA 00:03\r[download] 0.2% of 3.33MiB at 1.95MiB/s ETA 00:01 ' 

b'\r[download] 0.4% of 3.33MiB at 4.18MiB/s ETA 00:00 ' 

b'\r[download] 0.9% of 3.33MiB at 3.78MiB/s ETA 00:00 ' 

b'\r[download] 1.8% of 3.33MiB at 4.24MiB/s ETA 00:00 ' 

b'\r[download] 3.7% of 3.33MiB at 5.27MiB/s ETA 00:00 ' 
  • 我可以簡單地通過打印由功能提供的每個字符串,並設置end=''因爲那時它得到在Python控制檯通緝輸出注意控制檯中的\ r。 (使用PyCharm如果它的事項)

它長而凌亂的問題,這可以歸結爲,我可以得到的\r控制檯功能,在這種情況下,youtube-dl工作,沒有多餘的線條/空間,沒有百分比經過許多行?我對我的最後一個問題有點批評,所以我盡了最大的努力包括嘗試和觀察。

任何幫助表示讚賞!

根據要求編輯,以字節爲單位輸出,通過改變self.edit.append(...)

print(str(self.readAllStandardOutput())) 

byte output

,就是這樣,如果我輸出解碼,並與

print(str(self.readAllStandardOutput().data().decode('utf-8','ignore')), end='') 

enter image description here

打印

請注意,這只是顯示一行,因爲每次提供新字符串時都會更新。

+0

你能告訴你如何獲得輸出嗎? – eyllanesc

+0

@eyllanesc哪個輸出,控制檯中的輸出或QTextEdit中的輸出。 IIRC你做了我在這裏發佈的代碼示例。 (除了我對字符串輸出進行解碼的地方) – Thomasedv

+0

您可以截取屏幕截圖到控制檯中並將其放在帖子中 – eyllanesc

回答

2

要刪除\ n在每個我們使用strip()文字的末尾,那麼我們必須認識到,有個和子[download]線,這將足以解決問題,但在某些情況下,輸入我們get是單行文本中的幾行,那麼我們需要的是最後一行。

def readStdOutput(self): 
    data = self.readAllStandardOutput().data() 
    text = data.decode('utf-8','ignore').strip() 

    # get the last line of QTextEdit 
    self.edit.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor) 
    self.edit.moveCursor(QTextCursor.StartOfLine, QTextCursor.MoveAnchor) 
    self.edit.moveCursor(QTextCursor.End, QTextCursor.KeepAnchor) 
    lastLine = self.edit.textCursor().selectedText() 

    # Check if a percentage has already been placed. 
    if "[download]" in lastLine and "%" in lastLine: 
     self.edit.textCursor().removeSelectedText() 
     self.edit.textCursor().deletePreviousChar() 
     # Last line of text 
     self.edit.append("[download] "+text.split("[download]")[-1]) 
    else: 
     self.edit.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor) 
     if "[download]" in text and "%" in text: 
      # Last line of text 
      self.edit.append("[download] "+text.split("[download]")[-1]) 
     else: 
      self.edit.append(text) 
+0

這很好。唯一的問題是,它似乎有時會刪除100%。我正在研究它。 – Thomasedv

+0

解決了被刪除的100%。不完全確定我做了什麼......我認爲這是我清除了else語句中第二行的文本選擇。 (在else中的if語句之上的一行) – Thomasedv