2017-08-17 39 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