PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

时间:2023-03-10 04:19:28
PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

【概览】

1、显示原生Qwidget

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

2)使用布局

2、显示Qwidget的自定义类

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

      2)使用布局

【知识点】

1、显示原生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("",self) # 注意QLineEdit("0",self) 内的self!!
self.lineEdit.setGeometry(10,270,380,20)

【效果图】

PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

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("") # 注意QLineEdit("0") 内可以没self!! # 放入布局内
layout.addWidget(self.widget,0,0)
layout.addWidget(self.lineEdit,1,0)
self.setLayout(layout)

【效果图】

PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

2、显示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("",self)
self.lineEdit.setGeometry(10,260,380,20)

【效果图】

PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

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("") # 放入布局内
layout.addWidget(self.widget,0,0)
layout.addWidget(self.lineEdit,1,0)
self.setLayout(layout) self.setWindowTitle("4、QWidget的自定义类")

【效果图】

PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

【源代码】(依次)

 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("",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_())
 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("") # 放入布局内
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_())
 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("",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_())
 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("",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类里面,加上下面三句即可:

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

其中,第一句与 self.setBackgroundRole(QPalette.Midlight) 及 self.setStyleSheet("background-color:red;") 的第一感觉是等效的 ??? 各位自己体会吧:(

         self.setPalette(QPalette(Qt.red))

         self.setBackgroundRole(QPalette.Midlight)

         self.setStyleSheet("background-color:red;")

完整自定义的QWidget类:

 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在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

【完整代码】

 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("") # 这里可以不要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在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

【源代码】

 #!/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_())