这里的小“窗口”指Qwidget的自定义类,并不是指窗口(没有父类的控件称作窗口)。

【概览】

1、显示原生Qwidget

      1)不使用布局(绝对定位)

      2)使用布局

2、显示Qwidget的自定义类

      1)不使用布局(绝对定位)

      2)使用布局

一、显示原生Qwidget

1)不使用布局(绝对定位)

这种情况下,原生QWidget部件在实例化时必须带parent参数,当然parent = self,即:  self.widget = QWidget(self

class MyWindow(QWidget):
    def __init__(self, parent=None):
        super(MyWindow,self).__init__(parent)
        self.resize(400, 300)
        
        # 添加原生QWidget
        self.widget = QWidget(self) # 注意QWidget(self) 内的self!!
        self.widget.setGeometry(10,10,380,250)
        self.widget.setStyleSheet("background-color:grey;")
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0",self) # 注意QLineEdit("0",self) 内的self!!
        self.lineEdit.setGeometry(10,270,380,20)

效果图:

pyqt5 layout alignement灰色 pyqt5 addwidget_编辑框

 

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)

        #如果集成QMainWindow 则self.setLayout(layout) 替换成
        """
       # widget=QWidget()
       # widget.setLayout(layout)
       # self.setCentralWidget(widget)
        """

【效果图】

pyqt5 layout alignement灰色 pyqt5 addwidget_自定义_02

二、显示Qwidget的自定义类

1)不使用布局(绝对定位)

这种情况下,原生QWidget自定义类里面要放个东西!!不放东西的话,我也不会:(

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

        #QWidget自定义类里面要放个东西!!(不放东西的话,我也不会)
        self.gb = QGroupBox(self)
        self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到
        self.setStyleSheet("background-color:grey;")

        self.do_something()
        
    def do_something(self):
        pass


class MyWindow(QWidget):
    def __init__(self, parent=None):
        super(MyWindow,self).__init__(parent)
        self.resize(400,300)

        # 添加自定义部件(MyWidget)
        self.widget = MyWidget(self)
        self.widget.setGeometry(10,10,380,240)

        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0",self)
        self.lineEdit.setGeometry(10,260,380,20)

【效果图】

 

pyqt5 layout alignement灰色 pyqt5 addwidget_自定义_03

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()
        
        # 添加自定义部件(MyWidget)
        self.widget = MyWidget()
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0")

        # 放入布局内
        layout.addWidget(self.widget,0,0)
        layout.addWidget(self.lineEdit,1,0)
        self.setLayout(layout)

        self.setWindowTitle("4、QWidget的自定义类")

【效果图】

 

pyqt5 layout alignement灰色 pyqt5 addwidget_自定义类_04

 

【源代码】(依次)

1.1

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *



class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.resize(400, 300)
        
        # 添加原生QWidget
        self.widget = QWidget(self) # 注意QWidget(self) 内的self!!
        self.widget.setGeometry(10,10,380,250)
        self.widget.setStyleSheet("background-color:grey;")
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0",self) # 注意QLineEdit("0",self) 内的self!!
        self.lineEdit.setGeometry(10,270,380,20)

        self.setWindowTitle("1、原生QWidget")
        
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    dialog = MyWindow()
    dialog.show();
    sys.exit(app.exec_())

1.2

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *



class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.resize(400, 300)
        layout = QGridLayout()

        # 添加原生QWidget
        self.widget = QWidget()
        self.widget.setStyleSheet("background-color:grey;")
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0")

        # 放入布局内
        layout.addWidget(self.widget,0,0)
        layout.addWidget(self.lineEdit,1,0)
        self.setLayout(layout)

        self.setWindowTitle("2、原生QWidget")
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    dialog = MyWindow()
    dialog.show();
    sys.exit(app.exec_())

 

2.1

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


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

        #QWidget派生类里面要放个东西!!(不放东西的话,我也不会)
        self.gb = QGroupBox(self)
        self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到
        self.setStyleSheet("background-color:grey;")

        self.do_something()
        
    def do_something(self):
        pass


class MyWindow(QWidget):
    def __init__(self, parent=None):
        super(MyWindow,self).__init__(parent)
        self.resize(400,300)

        # 添加自定义部件(MyWidget)
        self.widget = MyWidget(self)
        self.widget.setGeometry(10,10,380,240)

        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0",self)
        self.lineEdit.setGeometry(10,260,380,20)

        self.setWindowTitle("3、QWidget的派生类")
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show();
    sys.exit(app.exec_())

2.2 

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget,self).__init__(parent)
        
        #QWidget派生类里面要放个东西!!(不放东西的话,我也不会)
        self.gb = QGroupBox(self)
        self.gb.setGeometry(0,0,200,200) #一定要有个东西把它撑起来!!不然看不到
        self.setStyleSheet("background-color:red;")
        self.do_something()
        
    def do_something(self):
        pass



class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.resize(400,300)
        layout = QGridLayout()
        
        # 添加自定义部件(MyWidget)
        self.widget = MyWidget(self) # sizeHint() = QSize(-1, -1)
        self.widget.setStyleSheet("background-color:red;")
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0",self) # sizeHint() = QSize(75, 20)

        # 放入布局内
        layout.addWidget(self.widget,0,0)
        layout.addWidget(self.lineEdit,1,0)
        self.setLayout(layout)


        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show();
    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;")
class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget,self).__init__(parent)

        self.setPalette(QPalette(Qt.red)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样
        self.setAutoFillBackground(True) #这一句是关键!!!自动填充背景
        self.setMinimumSize(100,100) # 这一句是辅助!!因为这个自定义的QWidget默认大小(sizeHint())是0,看不到!
        #self.setMaximumSize(500, 500)
        #self.setFixesSize(400,200)

        # 做一些别的事情......
        self.do_something()
        
    def do_something(self):
        pass
        

    # 如果需要的话,就覆写属性函数:sizeHint(默认尺寸)
    #def sizeHint(self):
    #    return QSize(400, 200)
    # 如果需要的话,就覆写属性函数:minimumSizeHint(最小尺寸)
    #def minimumSizeHint(self):
    #    return QSize(100, 100)

【效果图】

pyqt5 layout alignement灰色 pyqt5 addwidget_编辑框_05

完整代码:

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


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

        self.setPalette(QPalette(Qt.red)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样
        self.setAutoFillBackground(True) #这一句是关键!!!自动填充背景
        self.setMinimumSize(100,100) # 这一句是辅助!!因为这个自定义的QWidget默认大小(sizeHint())是0,看不到! 不过主窗体使用了布局的话,此句可省略
        #self.setMaximumSize(500, 500)
        #self.setFixesSize(400,200)

        # 做一些别的事情......
        self.do_something()
        
    def do_something(self):
        pass
        

    # 如果需要的话,就覆写属性函数:sizeHint(默认尺寸)
    #def sizeHint(self):
    #    return QSize(400, 200)
    # 如果需要的话,就覆写属性函数:minimumSizeHint(最小尺寸)
    #def minimumSizeHint(self):
    #    return QSize(100, 100)

        
        
        
class MyWindow(QWidget):
    def __init__(self, parent=None):
        super(MyWindow,self).__init__(parent)
        self.resize(400,300)
        layout = QGridLayout()
        
        # 添加自定义部件(MyWidget)
        self.widget = MyWidget() # 这里可以不要self
        
        # 添加编辑框(QLineEdit)
        self.lineEdit = QLineEdit("0") # 这里可以不要self

        # 放入布局内
        layout.addWidget(self.widget,0,0)
        layout.addWidget(self.lineEdit,1,0)
        self.setLayout(layout)

        self.setWindowTitle("5、完美显示QWidget的派生类")
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show();
    sys.exit(app.exec_())

再另外补充一个PyQt5应用实例: 飘动的文字

【效果图】

pyqt5 layout alignement灰色 pyqt5 addwidget_自定义_06

#!/usr/bin/env python


#############################################################################
##
## Copyright (C) 2013 Riverbank Computing Limited.
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
## All rights reserved.
##
## This file is part of the examples of PyQt.
##
## $QT_BEGIN_LICENSE:BSD$
## You may use this file under the terms of the BSD license as follows:
##
## "Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are
## met:
##   * Redistributions of source code must retain the above copyright
##     notice, this list of conditions and the following disclaimer.
##   * Redistributions in binary form must reproduce the above copyright
##     notice, this list of conditions and the following disclaimer in
##     the documentation and/or other materials provided with the
##     distribution.
##   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
##     the names of its contributors may be used to endorse or promote
##     products derived from this software without specific prior written
##     permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
## $QT_END_LICENSE$
##
#############################################################################


from PyQt5.QtCore import QBasicTimer
from PyQt5.QtGui import QColor, QFontMetrics, QPainter, QPalette
from PyQt5.QtWidgets import (QApplication, QDialog, QLineEdit, QVBoxLayout,
        QWidget)


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

        self.setBackgroundRole(QPalette.Midlight)
        self.setAutoFillBackground(True)

        newFont = self.font()
        newFont.setPointSize(newFont.pointSize() + 20)
        self.setFont(newFont)

        self.timer = QBasicTimer()
        self.text = ''

        self.step = 0;
        self.timer.start(60, self)   

    def paintEvent(self, event):
        sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38)

        metrics = QFontMetrics(self.font())
        x = (self.width() - metrics.width(self.text)) / 2
        y = (self.height() + metrics.ascent() - metrics.descent()) / 2
        color = QColor()

        painter = QPainter(self)

        for i, ch in enumerate(self.text):
            index = (self.step + i) % 16
            color.setHsv((15 - index) * 16, 255, 191)
            painter.setPen(color)
            painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), ch)
            x += metrics.width(ch)

    def setText(self, newText):
        self.text = newText

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.step += 1
            self.update()
        else:
            super(WigglyWidget, self).timerEvent(event)


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        wigglyWidget = WigglyWidget()
        lineEdit = QLineEdit()

        layout = QVBoxLayout()
        layout.addWidget(wigglyWidget)
        layout.addWidget(lineEdit)
        self.setLayout(layout)

        lineEdit.textChanged.connect(wigglyWidget.setText)

        lineEdit.setText("Hello world!")

        self.setWindowTitle("Wiggly")
        self.resize(360, 145)


if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)
    dialog = Dialog()
    dialog.show();
    sys.exit(app.exec_())

实例

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QTextEdit,QToolTip,QLabel,QVBoxLayout,QGridLayout
from PyQt5.QtGui import QIcon,QFont,QPixmap,QPalette
import PyQt5.QtCore as QtCore
from PyQt5.QtCore import Qt

class Icon(QWidget):
    def __init__(self,parent=None):
        super(Icon,self).__init__(parent)
        self.initUI()
    def initUI(self):

        # self.widget=builtinWidget(self)
        self.label1=QLabel(self)
        self.builtinwidget=builtinWidget()
        self.label3=QLabel(self)
        self.label4=QLabel(self)

        self.label1.setText("这是一个有颜色背景的固定标签")
        self.label1.setAutoFillBackground(True)
        palette=QPalette()
        palette.setColor(QPalette.Window,Qt.red)
        self.label1.setPalette(palette)
        self.label1.setAlignment(Qt.AlignCenter)



        self.label3.setAlignment(Qt.AlignCenter)
        self.label3.setToolTip('这是张图片')
        self.label3.setPixmap(QPixmap('i.png'))


        self.label4.setText("<A href='https://www.easyicon.net'>欢迎访问ICON网站</a>")
        self.label4.setAlignment(Qt.AlignRight)
        self.setToolTip("链接标签")





        vbox=QVBoxLayout()
        vbox.addWidget(self.label1)
        vbox.addStretch()
        vbox.addWidget(self.builtinwidget)
        vbox.addStretch()
        vbox.addWidget(self.label3)
        vbox.addStretch()
        vbox.addWidget(self.label4)
        vbox.addStretch()
        self.setLayout(vbox)

        self.label4.linkActivated.connect(self.openlink)

        QToolTip.setFont(QFont('TypeLand 康熙字典體試用版',24))
        self.setToolTip('这是一个<b>气泡提示</b>')


        self.setGeometry(300,300,400,400)
        self.setWindowTitle("Icon窗口")
        self.setWindowIcon(QIcon('iii.ico'))

    def openlink(self):
        print("打开链接")




class builtinWidget(QWidget):
    def __init__(self,parent=None):
        super(builtinWidget,self).__init__(parent)
        self.label2=QLabel('&name',self)
        self.label2Edit=QLineEdit(self)
        self.label2.setBuddy(self.label2Edit)
        subLayout=QGridLayout()
        subLayout.addWidget(self.label2,0,0)
        subLayout.addWidget(self.label2Edit,0,1,1,2)
        self.setLayout(subLayout)






if __name__ == '__main__':
    app=QApplication(sys.argv)
    mywin=Icon()
    mywin.show()
    sys.exit(app.exec_())

效果图:

pyqt5 layout alignement灰色 pyqt5 addwidget_自定义类_07