• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 41, 文章 - 8, 評論 - 8, 引用 - 0
            數據加載中……

            [Python][PyQt4]在 PyQt4 中定制組件

            在 PyQt4 中定制組件

            PyQt4 有豐富的組件。但是不可能提供所有的組件。PyQt4 中僅僅提供最常用的組件,像按鈕,文本框,滑塊等。如果我們需要特殊的組件,我們必須要自己創建。

            自定制組件可以使用工具包畫制工具創建。有兩種可能,一個程序員可以修改或提升一個已存在的工具,或是從零開始創建。

            Burning widget

            這是一個組件,我們可以在 Nero,K3B 或其它 CD/DVD 刻錄軟件。

            #!/usr/bin/python
            # -*- coding: utf-8 -*-
            """
            ZetCode PyQt4 tutorial
            In this example, we create a custom widget.
            author: Jan Bodnar
            website: zetcode.com
            last edited: October 2011
            """
            import sys
            from PyQt4 import QtGui, QtCore
            class Communicate(QtCore.QObject):
                updateBW = QtCore.pyqtSignal(int)
            class BurningWidget(QtGui.QWidget):
                def __init__(self):
                    super(BurningWidget, self).__init__()
                    self.initUI()
                def initUI(self):
                    self.setMinimumSize(1, 30)
                    self.value = 75
                    self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675]
                def setValue(self, value):
                    self.value = value
                def paintEvent(self, e):
                    qp = QtGui.QPainter()
                    qp.begin(self)
                    self.drawWidget(qp)
                    qp.end()
                def drawWidget(self, qp):
                    font = QtGui.QFont('Serif', 7, QtGui.QFont.Light)
                    qp.setFont(font)
                    size = self.size()
                    w = size.width()
                    h = size.height()
                    step = int(round(w / 10.0))
                    till = int(((w / 750.0) * self.value))
                    full = int(((w / 750.0) * 700))
                    if self.value >= 700:
                        qp.setPen(QtGui.QColor(255, 255, 255))
                        qp.setBrush(QtGui.QColor(255, 255, 184))
                        qp.drawRect(0, 0, full, h)
                        qp.setPen(QtGui.QColor(255, 175, 175))
                        qp.setBrush(QtGui.QColor(255, 175, 175))
                        qp.drawRect(full, 0, till-full, h)
                    else:
                        qp.setPen(QtGui.QColor(255, 255, 255))
                        qp.setBrush(QtGui.QColor(255, 255, 184))
                        qp.drawRect(0, 0, till, h)
                    pen = QtGui.QPen(QtGui.QColor(20, 20, 20), 1,
                        QtCore.Qt.SolidLine)
                    qp.setPen(pen)
                    qp.setBrush(QtCore.Qt.NoBrush)
                    qp.drawRect(0, 0, w-1, h-1)
                    j = 0
                    for i in range(step, 10*step, step):
                        qp.drawLine(i, 0, i, 5)
                        metrics = qp.fontMetrics()
                        fw = metrics.width(str(self.num[j]))
                        qp.drawText(i-fw/2, h/2, str(self.num[j]))
                        j = j + 1
            class Example(QtGui.QWidget):
                def __init__(self):
                    super(Example, self).__init__()
                    self.initUI()
                def initUI(self):
                    sld = QtGui.QSlider(QtCore.Qt.Horizontal, self)
                    sld.setFocusPolicy(QtCore.Qt.NoFocus)
                    sld.setRange(1, 750)
                    sld.setValue(75)
                    sld.setGeometry(30, 40, 150, 30)
                    self.c = Communicate()
                    self.wid = BurningWidget()
                    self.c.updateBW[int].connect(self.wid.setValue)
                    sld.valueChanged[int].connect(self.changeValue)
                    hbox = QtGui.QHBoxLayout()
                    hbox.addWidget(self.wid)
                    vbox = QtGui.QVBoxLayout()
                    vbox.addStretch(1)
                    vbox.addLayout(hbox)
                    self.setLayout(vbox)
                    self.setGeometry(300, 300, 390, 210)
                    self.setWindowTitle('Burning widget')
                    self.show()
                def changeValue(self, value):
                    self.c.updateBW.emit(value)
                    self.wid.repaint()
            def main():
                app = QtGui.QApplication(sys.argv)
                ex = Example()
                sys.exit(app.exec_())
            if __name__ == '__main__':
                main()
            

            在這個例子中,我們有一個 QtGui.QSlider 和一個自定制組件。滑塊控制了自定制組件。這個組件顯示一個媒介總的容量以及剩余的容量。這里最小的值是 1,最大是 750 。如果我們到達 700 ,我們開始畫紅色。這是用于指示過度燒制。

            組件放在窗口的底部。這通過一個 QtGui.QHBoxLayoutQtGui.QVBoxLayout 實現。

            class BurningWidget(QtGui.QWidget):
                def __init__(self):
                    super(BurningWidget, self).__init__()
            

            這個組件基于 QtGui.QWidget 組件。

            self.setMinimumSize(1, 30)
            

            我們更改了組件最小的大小(高度)。默認的值是一點點小。

            font = QtGui.QFont('Serif', 7, QtGui.QFont.Light)
            qp.setFont(font)
            

            我們用小于默認的字體。這適合于我們的需要。

            size = self.size()
            w = size.width()
            h = size.height()
            step = int(round(w / 10.0))
            till = int(((w / 750.0) * self.value))
            full = int(((w / 750.0) * 700))
            

            我們動態地繪制組件。窗口越大,組件會越大。反之亦然。這就是為何我們要計算組件的大小。參數 till 決定了要畫多少。此值來自于滑塊組件。這是整個區域的部分值。參數 full 決定了什么時候開始繪制紅色部分。注意,此處使用了浮點運算,是為更高的精度。

            真正繪制時包含三個部分。我們先繪制黃色或紅色和黃色的矩形。然后繪制垂直的線,主要用于分割組件。最后是繪制數字,用于指示媒介的大小。

            metrics = qp.fontMetrics()
            fw = metrics.width(str(self.num[j]))
            qp.drawText(i-fw/2, h/2, str(self.num[j]))
            

            我們使用字體度量來繪制文本。我們必須要知道文本的寬度來居中繪制。

            def changeValue(self, value):
                self.c.updateBW.emit(value)
                self.wid.repaint()
            

            我們移動滑塊時, changeValue() 方法就被調用了。在此方法內部,我們發送了自定義的 updateBW 信號,并且帶了一個參數。這個參數是當前滑塊的值。這個值用于計算在 Burning 這個組件中要繪制多少。自定義的組件然后被重繪。


            本部分,我們創建了自己的組件。

            posted on 2012-02-12 10:17 mirguest 閱讀(1212) 評論(0)  編輯 收藏 引用 所屬分類: Python

            亚洲精品无码久久久影院相关影片| 国产69精品久久久久9999| 国产精品午夜久久| 国内精品久久久久久久亚洲| 久久这里的只有是精品23| 亚洲AV无码久久精品成人| 国内精品久久久久影院免费| 久久综合综合久久狠狠狠97色88| 亚洲国产成人精品久久久国产成人一区二区三区综 | 91精品国产色综合久久| 伊人久久大香线蕉无码麻豆| 99久久免费国产特黄| 久久久精品免费国产四虎| 大香伊人久久精品一区二区| 久久www免费人成看国产片| 久久久久人妻一区二区三区 | 久久久黄片| 国产AV影片久久久久久| 久久福利资源国产精品999| 97久久久久人妻精品专区| 国产精品久久婷婷六月丁香| 中文字幕亚洲综合久久| 亚洲午夜精品久久久久久人妖| 久久久久久久久久久精品尤物| 国产综合免费精品久久久| 精品午夜久久福利大片| 欧洲精品久久久av无码电影| 模特私拍国产精品久久| 国产成人精品久久亚洲| 久久精品国产99国产电影网 | 亚洲中文久久精品无码ww16| 伊人色综合久久天天人手人婷 | 久久99久久99小草精品免视看| 丁香色欲久久久久久综合网| 午夜视频久久久久一区| 人人狠狠综合久久亚洲| 久久久久97国产精华液好用吗| 精品国产综合区久久久久久 | 亚洲精品高清国产一久久| 久久久久免费精品国产| 秋霞久久国产精品电影院|