这里的小“窗口”指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)
效果图:
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)
"""
【效果图】
二、显示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)
【效果图】
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的自定义类")
【效果图】
【源代码】(依次)
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)
【效果图】
完整代码:
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应用实例: 飘动的文字
【效果图】
#!/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_())
效果图: