我基于https://stackoverflow.com/a/2714554/6859682使用QAbstractButton创建了一组像素映射按钮(PicButton),并希望将它们添加到滚动区域中,以便用户可以水平滚动。但是,我需要
我当前代码的问题是,高度过高时,像素图按钮会受到挤压。
当高度足够小以使所有按钮都适合窗口时,我能够使纵横比保持恒定。我在下面附加我的PicButton类。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen
def testPixmap(r = 255,g = 0,b = 0, a = 255,size =(200,200)):
px = QtGui.QPixmap(size[0],size[1])
color = QtGui.QColor(r,g,b,a)
px.fill(color)
return px
class PicButton(QtWidgets.QAbstractButton):
checked = QtCore.pyqtSignal(object, QtCore.QRect)
def __init__(self, name, parent=None, w = 200, h = 200):
self.w = w; self.h = h; self.name = name
super(PicButton, self).__init__(parent)
pixmap = testPixmap(255,0,0)
self.resetPixmaps(pixmap); self.pixmap = pixmap
self.setCheckable(True); self.setChecked(False)
self.pressed.connect(self.update)
self.released.connect(self.blank)
def resetPixmaps(self, pixmap):
self.pixmap_hover = testPixmap(20,125,200,128)
self.pixmap_pressed = testPixmap(30,180,200,128)
def blank(self):
self.setChecked(True)
def paintEvent(self, event):
pix = self.pixmap_hover if self.underMouse() else self.pixmap
if self.isChecked():
self.checked.emit( self.name, event.rect())
pix = self.pixmap_pressed
size = self.size()
scaledPix = pix.scaledToHeight(size.height(), Qt.SmoothTransformation)
# start painting the label from left upper corner
point = QtCore.QPoint(0,0)
point.setX((size.width() - scaledPix.width())/2)
point.setY((size.height() - scaledPix.height())/2)
painter = QPainter(self)
painter.drawPixmap(point, scaledPix)
def otherBoxChecked(self, func, rect):
if self.isChecked():
pix = self.pixmap; painter = QPainter(self); painter.drawPixmap(rect, pix)
self.setChecked(False)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return QtCore.QSize(self.w, self.h)
在所有按钮都不能容纳高度的情况下,我想激活滚动条并保持按钮的长宽比。有关如何执行此操作的任何想法?我附上下面的窗口代码以确保完整性
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
buttons = ['str(i)' for i in range(10)]
HB2layout = QtWidgets.QHBoxLayout()
self.maskButtons = [PicButton(button) for button in buttons]
for maskButton, mb in zip(self.maskButtons, range(len(self.maskButtons))):
for maskConnect, mc in zip(self.maskButtons, range(len(self.maskButtons))):
if mb!=mc:
maskButton.checked.connect(maskConnect.otherBoxChecked)
for button in self.maskButtons:
HB2layout.addWidget(button)
self.scrollArea = QtWidgets.QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollArea.setMaximumHeight(200)
self.scrollArea.setLayout(HB2layout)
self.scrollArea.show()
Vlayout = QtWidgets.QVBoxLayout(self)
Vlayout.addWidget(self.scrollArea)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 800, 200)
window.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
已添加
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen
def testPixmap(r = 255,g = 0,b = 0, a = 255,size =(200,200)):
px = QtGui.QPixmap(size[0],size[1])
color = QtGui.QColor(r,g,b,a)
px.fill(color)
return px
class PicButton(QtWidgets.QAbstractButton):
checked = QtCore.pyqtSignal(object, QtCore.QRect)
def __init__(self, name, parent=None, w = 200, h = 200):
self.w = w; self.h = h; self.name = name
super(PicButton, self).__init__(parent)
pixmap = testPixmap(255,0,0)
self.resetPixmaps(pixmap); self.pixmap = pixmap
self.setCheckable(True); self.setChecked(False)
self.pressed.connect(self.update)
self.released.connect(self.blank)
def resetPixmaps(self, pixmap):
self.pixmap_hover = testPixmap(20,125,200,128)
self.pixmap_pressed = testPixmap(30,180,200,128)
def blank(self):
self.setChecked(True)
def paintEvent(self, event):
pix = self.pixmap_hover if self.underMouse() else self.pixmap
if self.isChecked():
self.checked.emit( self.name, event.rect())
pix = self.pixmap_pressed
size = self.size()
scaledPix = pix.scaledToHeight(size.height(), Qt.SmoothTransformation)
# start painting the label from left upper corner
point = QtCore.QPoint(0,0)
point.setX((size.width() - scaledPix.width())/2)
point.setY((size.height() - scaledPix.height())/2)
painter = QPainter(self)
painter.drawPixmap(point, scaledPix)
def otherBoxChecked(self, func, rect):
if self.isChecked():
pix = self.pixmap; painter = QPainter(self); painter.drawPixmap(rect, pix)
self.setChecked(False)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return QtCore.QSize(self.w, self.h)
class View(QtWidgets.QGraphicsView):
def __init__(self):
super(View,self).__init__()
self.pic_scene = QtWidgets.QGraphicsScene()
self.neighborhood = 200
buttons = ['str(i)' for i in range(10)]
self.maskButtons = [PicButton(button) for button in buttons]
for maskButton, mb in zip(self.maskButtons , range(len(self.maskButtons ))):
for maskConnect, mc in zip(self.maskButtons , range(len(self.maskButtons ))):
if mb!=mc:
maskButton.checked.connect(maskConnect.otherBoxChecked)
self.pic_scene.setSceneRect(0,0,10000,200)
for i,item in enumerate(self.maskButtons ):
item.setGeometry(self.neighborhood*i,item.geometry().y(),item.geometry().width(),item.geometry().height())
self.pic_scene.addWidget(item)
self.setScene(self.pic_scene)
self.setMaximumHeight(200)
self.setGeometry(500,500,5000,200)
def paintEvent(self,event):
for k,i in enumerate(self.maskButtons ):
rect = i.geometry()
#eventually,width = height
rect.setSize(QtCore.QSize(self.height(),self.height()))
self.neighborhood = self.height()
rect.setX(self.height()*k)
rect.setY(rect.y())
i.setGeometry(rect)
self.pic_scene.addWidget(i)
return QtWidgets.QGraphicsView.paintEvent(self,event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = View()
window.setGeometry(500, 300, 800, 200)
window.show()
sys.exit(app.exec_())
很抱歉没有一次填写您想要的答案。
QAbstractButton版本
是的,我没有使用QAbstractButton,这已经挂在我头上了。 这是QAbstractButton版本。您将能够自定义所需的按钮。
从PyQt5导入QtCore,QtGui,QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen
class PicButton(QtWidgets.QAbstractButton):
def __init__(self,x=0,y=0,width=200,height=200):
super(PicButton,self).__init__()
self.setGeometry(x,y,width,height)
def paintEvent(self,event):
painter = QtGui.QPainter()
if not painter.isActive():
painter.begin(self)
brush = QtGui.QBrush()
brush.setColor(QtGui.QColor(Qt.red))
brush.setStyle(Qt.SolidPattern)
painter.setBrush(brush)
painter.drawRect(QtCore.QRect(0,0,200,200))
painter.end()
class View(QtWidgets.QGraphicsView):
def __init__(self):
super(View,self).__init__()
self.pic_scene = QtWidgets.QGraphicsScene()
self.neighborhood = 200
self.rect_items = [PicButton() for i in range(10)]
self.pic_scene.setSceneRect(0,0,10000,200)
for i,item in enumerate(self.rect_items):
item.setGeometry(self.neighborhood*i,item.geometry().y(),item.geometry().width(),item.geometry().height())
self.pic_scene.addWidget(item)
self.setScene(self.pic_scene)
self.setMaximumHeight(200)
self.setGeometry(500,500,5000,200)
def paintEvent(self,event):
for k,i in enumerate(self.rect_items):
rect = i.geometry()
#eventually,width = height
rect.setSize(QtCore.QSize(self.height(),self.height()))
self.neighborhood = self.height()
rect.setX(self.height()*k)
rect.setY(rect.y())
i.setGeometry(rect)
self.pic_scene.addWidget(i)
return QtWidgets.QGraphicsView.paintEvent(self,event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = View()
window.setGeometry(500, 300, 800, 200)
window.show()
sys.exit(app.exec_())
新
因为我接受了评论,所以我尝试阐述QGraphicsView和QGraphicsScene的场合。
但这只是结果。此代码可能不受欢迎。 无论如何,我希望您执行此代码。 希望你喜欢。
如果您想了解详细信息,请写评论。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen
class PicRectItem(QtWidgets.QGraphicsRectItem):
def __init__(self,x=0,y=0,width=200,height=200):
super(PicRectItem,self).__init__()
self.setRect(x,y,width,height)
brush = QtGui.QBrush()
brush.setColor(QtGui.QColor(Qt.red))
brush.setStyle(Qt.SolidPattern)
self.setBrush(brush)
class View(QtWidgets.QGraphicsView):
def __init__(self):
super(View,self).__init__()
self.pic_scene = QtWidgets.QGraphicsScene()
self.neighborhood = 200
self.rect_items = [PicRectItem() for i in range(10)]
for i,item in enumerate(self.rect_items):
item.setRect(self.neighborhood*i,item.y(),item.rect().width(),item.rect().height())
for i in self.rect_items:
self.pic_scene.addItem(i)
self.setScene(self.pic_scene)
self.setMaximumHeight(200)
def paintEvent(self,event):
for k,i in enumerate(self.rect_items):
rect = i.rect()
#eventually,width = height
rect.setSize(QtCore.QSizeF(self.height(),self.height()))
self.neighborhood = self.height()
i.setRect(rect)
self.pic_scene.addItem(i)
rect = i.rect()
rect.setX(self.height()*k)
rect.setY(rect.y())
i.setRect(rect)
return QtWidgets.QGraphicsView.paintEvent(self,event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = View()
window.setGeometry(500, 300, 800, 200)
window.show()
sys.exit(app.exec_())
上一个
我不确定您想要什么,您要这样做吗? 如果不是,我将删除此答案或重写。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QPixmap, QPainter, QPen
def testPixmap(r = 255,g = 0,b = 0, a = 255,size =(200,200)):
px = QtGui.QPixmap(size[0],size[1])
color = QtGui.QColor(r,g,b,a)
px.fill(color)
return px
class PicButton(QtWidgets.QAbstractButton):
checked = QtCore.pyqtSignal(object, QtCore.QRect)
def __init__(self, name, parent=None, w = 200, h = 200):
self.w = w; self.h = h; self.name = name
super(PicButton, self).__init__(parent)
pixmap = testPixmap(255,0,0)
self.resetPixmaps(pixmap); self.pixmap = pixmap
self.setCheckable(True); self.setChecked(False)
self.pressed.connect(self.update)
self.released.connect(self.blank)
def resetPixmaps(self, pixmap):
self.pixmap_hover = testPixmap(20,125,200,128)
self.pixmap_pressed = testPixmap(30,180,200,128)
def blank(self):
self.setChecked(True)
def paintEvent(self, event):
pix = self.pixmap_hover if self.underMouse() else self.pixmap
if self.isChecked():
self.checked.emit( self.name, event.rect())
pix = self.pixmap_pressed
size = self.size()
scaledPix = pix.scaledToHeight(size.height(), Qt.SmoothTransformation)
# start painting the label from left upper corner
point = QtCore.QPoint(0,0)
point.setX((size.width() - scaledPix.width())/2)
point.setY((size.height() - scaledPix.height())/2)
painter = QPainter(self)
painter.drawPixmap(point, scaledPix)
def otherBoxChecked(self, func, rect):
if self.isChecked():
pix = self.pixmap; painter = QPainter(self); painter.drawPixmap(rect, pix)
self.setChecked(False)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return QtCore.QSize(self.w, self.h)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
buttons = ['str(i)' for i in range(10)]
HB2layout = QtWidgets.QHBoxLayout()
self.maskButtons = [PicButton(button) for button in buttons]
for maskButton, mb in zip(self.maskButtons, range(len(self.maskButtons))):
for maskConnect, mc in zip(self.maskButtons, range(len(self.maskButtons))):
if mb!=mc:
maskButton.checked.connect(maskConnect.otherBoxChecked)
for button in self.maskButtons:
HB2layout.addWidget(button)
self.scrollChildArea = QtWidgets.QWidget()
self.scrollChildArea.setLayout(HB2layout)
self.scrollArea = QtWidgets.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollArea.setMaximumHeight(200)
self.scrollArea.setWidget(self.scrollChildArea)
self.scrollArea.show()
Vlayout = QtWidgets.QVBoxLayout()
Vlayout.addWidget(self.scrollArea)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 800, 200)
sys.exit(app.exec_())