【概览】
1、显示原生Qwidget
1)不使用布局(绝对定位)
2)使用布局
2、显示Qwidget的自定义类
1)不使用布局(绝对定位)
2)使用布局
【知识点】
1、显示原生Qwidget
1)不使用布局(绝对定位)
这种情况下,原生QWidget部件在实例化时必须带parent参数,当然parent = self,即: self.widget = QWidget(self)
1 class MyWindow(QWidget): 2 def __init__(self, parent=None): 3 super(MyWindow,self).__init__(parent) 4 self.resize(400, 300) 5 6 # 添加原生QWidget 7 self.widget = QWidget(self) # 注意QWidget(self) 内的self!! 8 self.widget.setGeometry(10,10,380,250) 9 self.widget.setStyleSheet("background-color:grey;")10 11 # 添加编辑框(QLineEdit)12 self.lineEdit = QLineEdit("0",self) # 注意QLineEdit("0",self) 内的self!!13 self.lineEdit.setGeometry(10,270,380,20)
【效果图】
2)使用布局
这种情况下,原生QWidget部件在实例化时可以不带parent参数,parent =None / self都行,即: self.widget = QWidget()或 self.widget = QWidget(self)
class MyWindow(QWidget): def __init__(self, parent=None): super(MyWindow,self).__init__(parent) self.resize(400, 300) layout = QGridLayout() # 添加原生QWidget self.widget = QWidget() # 注意QWidget() 内可以没有self!! self.widget.setStyleSheet("background-color:grey;") # 添加编辑框(QLineEdit) self.lineEdit = QLineEdit("0") # 注意QLineEdit("0") 内可以没self!! # 放入布局内 layout.addWidget(self.widget,0,0) layout.addWidget(self.lineEdit,1,0) self.setLayout(layout)
【效果图】
2、显示Qwidget的自定义类
1)不使用布局(绝对定位)
这种情况下,原生QWidget自定义类里面要放个东西!!不放东西的话,我也不会:(
1 class MyWidget(QWidget): 2 def __init__(self, parent=None): 3 super(MyWidget,self).__init__(parent) 4 5 #QWidget自定义类里面要放个东西!!(不放东西的话,我也不会) 6 self.gb = QGroupBox(self) 7 self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到 8 self.setStyleSheet("background-color:grey;") 9 10 self.do_something()11 12 def do_something(self):13 pass14 15 16 class MyWindow(QWidget):17 def __init__(self, parent=None):18 super(MyWindow,self).__init__(parent)19 self.resize(400,300)20 21 # 添加自定义部件(MyWidget)22 self.widget = MyWidget(self)23 self.widget.setGeometry(10,10,380,240)24 25 26 # 添加编辑框(QLineEdit)27 self.lineEdit = QLineEdit("0",self)28 self.lineEdit.setGeometry(10,260,380,20)29 30
【效果图】
2)使用布局
这种情况下,原生QWidget部件在实例化时可以不带parent参数,parent =None / self都行,即: self.widget = QWidget()或 self.widget = QWidget(self)
1 class MyWindow(QWidget): 2 def __init__(self, parent=None): 3 super(MyWindow,self).__init__(parent) 4 self.resize(400,300) 5 layout = QGridLayout() 6 7 # 添加自定义部件(MyWidget) 8 self.widget = MyWidget() 9 10 # 添加编辑框(QLineEdit)11 self.lineEdit = QLineEdit("0")12 13 # 放入布局内14 layout.addWidget(self.widget,0,0)15 layout.addWidget(self.lineEdit,1,0)16 self.setLayout(layout)17 18 self.setWindowTitle("4、QWidget的自定义类")
【效果图】
【源代码】(依次)
1 from PyQt5.QtCore import * 2 from PyQt5.QtGui import * 3 from PyQt5.QtWidgets import * 4 5 6 7 class MyWindow(QWidget): 8 def __init__(self): 9 super(MyWindow,self).__init__()10 self.resize(400, 300)11 12 # 添加原生QWidget13 self.widget = QWidget(self) # 注意QWidget(self) 内的self!!14 self.widget.setGeometry(10,10,380,250)15 self.widget.setStyleSheet("background-color:grey;")16 17 # 添加编辑框(QLineEdit)18 self.lineEdit = QLineEdit("0",self) # 注意QLineEdit("0",self) 内的self!!19 self.lineEdit.setGeometry(10,270,380,20)20 21 self.setWindowTitle("1、原生QWidget")22 23 24 if __name__ == '__main__':25 import sys26 app = QApplication(sys.argv)27 dialog = MyWindow()28 dialog.show();29 sys.exit(app.exec_())
1 from PyQt5.QtCore import * 2 from PyQt5.QtGui import * 3 from PyQt5.QtWidgets import * 4 5 6 7 class MyWindow(QWidget): 8 def __init__(self): 9 super(MyWindow,self).__init__()10 self.resize(400, 300)11 layout = QGridLayout()12 13 # 添加原生QWidget14 self.widget = QWidget()15 self.widget.setStyleSheet("background-color:grey;")16 17 # 添加编辑框(QLineEdit)18 self.lineEdit = QLineEdit("0")19 20 # 放入布局内21 layout.addWidget(self.widget,0,0)22 layout.addWidget(self.lineEdit,1,0)23 self.setLayout(layout)24 25 self.setWindowTitle("2、原生QWidget")26 27 if __name__ == '__main__':28 import sys29 app = QApplication(sys.argv)30 dialog = MyWindow()31 dialog.show();32 sys.exit(app.exec_())
1 from PyQt5.QtCore import * 2 from PyQt5.QtGui import * 3 from PyQt5.QtWidgets import * 4 5 6 class MyWidget(QWidget): 7 def __init__(self, parent=None): 8 super(MyWidget,self).__init__(parent) 9 10 #QWidget派生类里面要放个东西!!(不放东西的话,我也不会)11 self.gb = QGroupBox(self)12 self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到13 self.setStyleSheet("background-color:grey;")14 15 self.do_something()16 17 def do_something(self):18 pass19 20 21 class MyWindow(QWidget):22 def __init__(self, parent=None):23 super(MyWindow,self).__init__(parent)24 self.resize(400,300)25 26 # 添加自定义部件(MyWidget)27 self.widget = MyWidget(self)28 self.widget.setGeometry(10,10,380,240)29 30 31 # 添加编辑框(QLineEdit)32 self.lineEdit = QLineEdit("0",self)33 self.lineEdit.setGeometry(10,260,380,20)34 35 self.setWindowTitle("3、QWidget的派生类")36 37 if __name__ == '__main__':38 import sys39 app = QApplication(sys.argv)40 window = MyWindow()41 window.show();42 sys.exit(app.exec_())
1 from PyQt5.QtCore import * 2 from PyQt5.QtGui import * 3 from PyQt5.QtWidgets import * 4 5 class MyWidget(QWidget): 6 def __init__(self, parent=None): 7 super(MyWidget,self).__init__(parent) 8 9 #QWidget派生类里面要放个东西!!(不放东西的话,我也不会)10 self.gb = QGroupBox(self)11 self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到12 self.setStyleSheet("background-color:red;")13 self.do_something()14 15 def do_something(self):16 pass17 18 19 20 class MyWindow(QWidget):21 def __init__(self):22 super(MyWindow,self).__init__()23 self.resize(400,300)24 layout = QGridLayout()25 26 # 添加自定义部件(MyWidget)27 self.widget = MyWidget(self) # sizeHint() = QSize(-1, -1)28 self.widget.setStyleSheet("background-color:red;")29 30 # 添加编辑框(QLineEdit)31 self.lineEdit = QLineEdit("0",self) # sizeHint() = QSize(75, 20)32 33 # 放入布局内34 layout.addWidget(self.widget,0,0)35 layout.addWidget(self.lineEdit,1,0)36 self.setLayout(layout)37 38 39 40 if __name__ == '__main__':41 import sys42 app = QApplication(sys.argv)43 window = MyWindow()44 window.show();45 sys.exit(app.exec_())
【增补】
皇天不负苦心人,终于完美解决了。
问题出在自定义的QWidget类里面,加上下面三句即可:
1 self.setPalette(QPalette(Qt.red)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样2 self.setAutoFillBackground(True) # 这一句是关键!!!自动填充背景3 self.setMinimumSize(100,100) # 这一句是辅助!!因为这个自定义的QWidget默认大小(sizeHint())是0,看不到!
其中,第一句与 self.setBackgroundRole(QPalette.Midlight) 及 self.setStyleSheet("background-color:red;") 的第一感觉是等效的 ??? 各位自己体会吧:(
1 self.setPalette(QPalette(Qt.red))2 3 self.setBackgroundRole(QPalette.Midlight)4 5 self.setStyleSheet("background-color:red;")
完整自定义的QWidget类:
1 class MyWidget(QWidget): 2 def __init__(self, parent=None): 3 super(MyWidget,self).__init__(parent) 4 5 self.setPalette(QPalette(Qt.red)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样 6 self.setAutoFillBackground(True) #这一句是关键!!!自动填充背景 7 self.setMinimumSize(100,100) # 这一句是辅助!!因为这个自定义的QWidget默认大小(sizeHint())是0,看不到! 8 #self.setMaximumSize(500, 500) 9 #self.setFixesSize(400,200)10 11 # 做一些别的事情......12 self.do_something()13 14 def do_something(self):15 pass16 17 18 # 如果需要的话,就覆写属性函数:sizeHint(默认尺寸)19 #def sizeHint(self):20 # return QSize(400, 200)21 # 如果需要的话,就覆写属性函数:minimumSizeHint(最小尺寸)22 #def minimumSizeHint(self):23 # return QSize(100, 100)
【效果图】
【完整代码】
1 from PyQt5.QtCore import * 2 from PyQt5.QtGui import * 3 from PyQt5.QtWidgets import * 4 5 6 class MyWidget(QWidget): 7 def __init__(self, parent=None): 8 super(MyWidget,self).__init__(parent) 9 10 self.setPalette(QPalette(Qt.red)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样11 self.setAutoFillBackground(True) #这一句是关键!!!自动填充背景12 self.setMinimumSize(100,100) # 这一句是辅助!!因为这个自定义的QWidget默认大小(sizeHint())是0,看不到! 不过主窗体使用了布局的话,此句可省略13 #self.setMaximumSize(500, 500)14 #self.setFixesSize(400,200)15 16 # 做一些别的事情......17 self.do_something()18 19 def do_something(self):20 pass21 22 23 # 如果需要的话,就覆写属性函数:sizeHint(默认尺寸)24 #def sizeHint(self):25 # return QSize(400, 200)26 # 如果需要的话,就覆写属性函数:minimumSizeHint(最小尺寸)27 #def minimumSizeHint(self):28 # return QSize(100, 100)29 30 31 32 33 class MyWindow(QWidget):34 def __init__(self, parent=None):35 super(MyWindow,self).__init__(parent)36 self.resize(400,300)37 layout = QGridLayout()38 39 # 添加自定义部件(MyWidget)40 self.widget = MyWidget() # 这里可以不要self41 42 # 添加编辑框(QLineEdit)43 self.lineEdit = QLineEdit("0") # 这里可以不要self44 45 # 放入布局内46 layout.addWidget(self.widget,0,0)47 layout.addWidget(self.lineEdit,1,0)48 self.setLayout(layout)49 50 self.setWindowTitle("5、完美显示QWidget的派生类")51 52 if __name__ == '__main__':53 import sys54 app = QApplication(sys.argv)55 window = MyWindow()56 window.show();57 sys.exit(app.exec_())
再另外补充一个PyQt5应用实例: 飘动的文字
【效果图】
【源代码】
1 #!/usr/bin/env python 2 3 4 ############################################################################# 5 ## 6 ## Copyright (C) 2013 Riverbank Computing Limited. 7 ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 8 ## All rights reserved. 9 ## 10 ## This file is part of the examples of PyQt. 11 ## 12 ## $QT_BEGIN_LICENSE:BSD$ 13 ## You may use this file under the terms of the BSD license as follows: 14 ## 15 ## "Redistribution and use in source and binary forms, with or without 16 ## modification, are permitted provided that the following conditions are 17 ## met: 18 ## * Redistributions of source code must retain the above copyright 19 ## notice, this list of conditions and the following disclaimer. 20 ## * Redistributions in binary form must reproduce the above copyright 21 ## notice, this list of conditions and the following disclaimer in 22 ## the documentation and/or other materials provided with the 23 ## distribution. 24 ## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor 25 ## the names of its contributors may be used to endorse or promote 26 ## products derived from this software without specific prior written 27 ## permission. 28 ## 29 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 40 ## $QT_END_LICENSE$ 41 ## 42 ############################################################################# 43 44 45 from PyQt5.QtCore import QBasicTimer 46 from PyQt5.QtGui import QColor, QFontMetrics, QPainter, QPalette 47 from PyQt5.QtWidgets import (QApplication, QDialog, QLineEdit, QVBoxLayout, 48 QWidget) 49 50 51 class WigglyWidget(QWidget): 52 def __init__(self, parent=None): 53 super(WigglyWidget, self).__init__(parent) 54 55 self.setBackgroundRole(QPalette.Midlight) 56 self.setAutoFillBackground(True) 57 58 newFont = self.font() 59 newFont.setPointSize(newFont.pointSize() + 20) 60 self.setFont(newFont) 61 62 self.timer = QBasicTimer() 63 self.text = '' 64 65 self.step = 0; 66 self.timer.start(60, self) 67 68 def paintEvent(self, event): 69 sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38) 70 71 metrics = QFontMetrics(self.font()) 72 x = (self.width() - metrics.width(self.text)) / 2 73 y = (self.height() + metrics.ascent() - metrics.descent()) / 2 74 color = QColor() 75 76 painter = QPainter(self) 77 78 for i, ch in enumerate(self.text): 79 index = (self.step + i) % 16 80 color.setHsv((15 - index) * 16, 255, 191) 81 painter.setPen(color) 82 painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), ch) 83 x += metrics.width(ch) 84 85 def setText(self, newText): 86 self.text = newText 87 88 def timerEvent(self, event): 89 if event.timerId() == self.timer.timerId(): 90 self.step += 1 91 self.update() 92 else: 93 super(WigglyWidget, self).timerEvent(event) 94 95 96 class Dialog(QDialog): 97 def __init__(self, parent=None): 98 super(Dialog, self).__init__(parent) 99 100 wigglyWidget = WigglyWidget()101 lineEdit = QLineEdit()102 103 layout = QVBoxLayout()104 layout.addWidget(wigglyWidget)105 layout.addWidget(lineEdit)106 self.setLayout(layout)107 108 lineEdit.textChanged.connect(wigglyWidget.setText)109 110 lineEdit.setText("Hello world!")111 112 self.setWindowTitle("Wiggly")113 self.resize(360, 145)114 115 116 if __name__ == '__main__':117 118 import sys119 120 app = QApplication(sys.argv)121 dialog = Dialog()122 dialog.show();123 sys.exit(app.exec_())