在PyQt或PySide的QLineEdit中添加QProgress条

1 投票
1 回答
879 浏览
提问于 2025-04-18 03:42

你好,我想在 QLineEdit 后面加一个进度条,就像 Safari 浏览器或 IE 浏览器那样。所以我想知道怎么把进度条和我的 QLineEdit 连接起来,这样当用户输入路径完成后,进度条就能显示打开路径的进度!

from PyQt4 import QtGui, QtCore
import sys

class ProgressBar(QtGui.QProgressBar):
    """ docstring for ProgressBar
    """
    def __init__(self, parent=None):
        super(ProgressBar, self).__init__(parent)
        self.timer = QtCore.QBasicTimer()
        self.step = 0
        self.doAction()

    def timerEvent(self, e):

        if self.step >= 100:

            self.timer.stop()
            return

        self.step = self.step + 15
        self.setValue(self.step)

    def doAction(self):

        if self.timer.isActive():
            self.timer.stop()
        else:
            self.timer.start(100, self)




class MyLineEdit(QtGui.QLineEdit):
    """ docstring for MyLineEdit
    """
    def __init__(self, parent=None):
        super(MyLineEdit, self).__init__(parent)
        # I want to hook this bar at the backgroind of MyLineEdit
        pbar = ProgressBar()


class Example(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Example, self).__init__(parent)

        self.pbar = ProgressBar(self)
        self.editbx = MyLineEdit(self.pbar)
        newPalette = QtGui.QPalette()
        newPalette.setColor(self.editbx.backgroundRole(), QtCore.Qt.transparent)
        self.editbx.setPalette(newPalette)
        self.editbx.setText("Defaukt text set")
        self.editbx.setStyleSheet("QLineEdit { border:none;}")
        self.pbar.setStyleSheet("QProgressBar {border:none;}")

        self.initUI()

    def initUI(self):
        # self.pbar.setGeometry(30, 40, 200, 25)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QtGui.QProgressBar')
        self.show()



def main():
    app = QtGui.QApplication(sys.argv)
    win = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

我还想在用户输入的文本位置添加一个下拉框(QCombobox),这样可以列出其他已存在的文件夹。不过我不想用 QCompleter,因为它的样式和 QCombobox 不一样,而且我不想让用户输入一些不存在的内容。

任何帮助都会非常感谢。

1 个回答

2

我这里有一个例子,展示了一个QLineEdit(文本输入框)后面有一个进度条。这个例子受到了这个帖子很大的影响:http://www.qtcentre.org/threads/54758-Progress-bar-form-QLineEdit-issue

基本上,你需要自己来管理绘制的过程。不幸的是,当我尝试在QComboBox(下拉框)上做同样的事情时,似乎没有成功。我建议你在准备好后,专门发一个新问题,询问如何在QComboBox上绘制进度条!

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        QLineEdit.__init__(self, parent)
        self.timer = QBasicTimer()
        self.step = 0
        self.doAction()

    def timerEvent(self, e):
        if self.step >= 100:
            self.timer.stop()
            return

        self.step = self.step + 10
        self.repaint()        

    def doAction(self):
        if self.timer.isActive():
            self.timer.stop()
        else:
            self.timer.start(1000, self)

    def generateGradient(self, color):
        gradient = QLinearGradient(0, 0, 0, self.height());
        m_defaultBaseColor = self.palette().color(QPalette.Base)
        gradient.setColorAt(0, m_defaultBaseColor)
        gradient.setColorAt(0.15, color.lighter(120))
        gradient.setColorAt(0.5, color)
        gradient.setColorAt(0.85, color.lighter(120))
        gradient.setColorAt(1, m_defaultBaseColor)
        return gradient

    def paintEvent(self, event):
        p = QPainter(self)
        panel = QStyleOptionFrameV2()
        self.initStyleOption(panel)
        self.style().drawPrimitive(QStyle.PE_PanelLineEdit, panel, p, self)

        # an alternative to painting the QLineEdit is to do it only when the widget has focus and the progress bar is finished
        #if self.hasFocus() or self.step >= 100: QLineEdit.paintEvent(self, event)

        # however I've chosen to paint it always
        QLineEdit.paintEvent(self, event)

        painter = QPainter(self)
        lenap = QStyleOptionFrameV2()
        self.initStyleOption(lenap)
        backgroundRect = self.style().subElementRect(QStyle.SE_LineEditContents, lenap, self)

        # some alternative if statements you might like to use instead...
        #
        # if not self.hasFocus() and self.step < 100:
        # if self.step < 100:
        if True:
            loadingColor = QColor(116,192,250)
            painter.setBrush(self.generateGradient(loadingColor))
            painter.setPen(Qt.transparent)
            mid = int(backgroundRect.width()/100.0*self.step)
            progressRect = QRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height())
            painter.drawRect(progressRect)

            painter.setPen(Qt.SolidLine)
            painter.drawText(backgroundRect, Qt.AlignLeft|Qt.AlignVCenter, " " + self.text())


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self._control = QWidget()
        self.setCentralWidget(self._control)

        l = QVBoxLayout(self._control)
        e = MyLineEdit()
        l.addWidget(e)
        b = QPushButton('a')
        l.addWidget(b)

        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Window()
    sys.exit(app.exec_())

撰写回答