我正在试图弄清楚如何创建一个完全可调整大小的自定义扩展小部件,但能够在不受布局限制的情况下自由放置标签和按钮。
这是我想要实现的目标的粗略概念:
我的想法是我会使用带有某种标题集的QGroupBox,里面会有一种布局,以确保在调整QGroupBox大小时可以调整内部的内容,并使用带有图像的自定义按钮箭头放在QGroupBox角落的顶部,完全忽略了QGroupBox的布局。这意味着QGroupBox必须包含在没有布局的区域中。不幸的是,这意味着QGroupBox将不再是"可调整大小"因为它没有遵循布局。所以我想知道如何做到这一点。
到目前为止,我有这段代码:
from PyQt4 import QtCore, QtGui
import sys
class Window(QtGui.QWidget):
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('Test UI')
self.setMinimumSize(75, 50)
#self.setMaximumSize(250, 500)
self.oldWidth = 0.0
self.oldHeight = 0.0
self.oldButtonPosX = 0.0
self.oldButtonPosY = 0.0
self.resized.connect(self.someFunction)
position = QtGui.QCursor.pos()
self.move(position)
self.uiWidget = QtGui.QWidget()
self.freeWidget = QtGui.QWidget(self.uiWidget)
self.verticalLayout = QtGui.QVBoxLayout(self.freeWidget)
self.exportPushButton = QtGui.QPushButton(self.freeWidget)
self.exportPushButton.setText('Export')
self.verticalLayout.addWidget(self.exportPushButton)
self.exportPushButton2 = QtGui.QPushButton(self.freeWidget)
self.exportPushButton2.setText('Export')
self.verticalLayout.addWidget(self.exportPushButton2)
self.testButton = QtGui.QPushButton(self.uiWidget)
self.testButton.setText('.')
self.testButton.setGeometry(5,5,20,20)
#self.testButton = QtGui.QPushButton(self.uiWidget)
self.lyt = QtGui.QVBoxLayout()
self.lyt.addWidget(self.uiWidget)
self.setLayout(self.lyt)
#self.oldWidth = self.width()
#self.oldHeight = self.height()
def resizeEvent(self, event):
self.resized.emit()
self.oldWidth = self.width()
self.oldHeight = self.height()
self.oldButtonPosX = self.testButton.x()
self.oldButtonPosY = self.testButton.y()
return QtGui.QWidget.resizeEvent(self, event)
def someFunction(self):
newWidth = self.width() - 20.0
newHeight = self.height() - 20.0
self.freeWidget.setGeometry(0,0,newWidth,newHeight)
newButtonX = self.oldButtonPosX + (self.oldWidth - newWidth)
print self.oldButtonPosX
print 'self.oldWidth: %s' %self.oldWidth
print 'newWidth: %s' %newWidth
value = self.oldWidth-newWidth
print 'difference: %s' %str(value)
newButtonY = 20 + (self.oldHeight - newHeight)
#self.freeWidget.setGeometry(self.geometry)
#print 'Resizing label'
#
if self.oldButtonPosX != 0.0:
self.testButton.setGeometry(newButtonX,newButtonY,20,20)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
通过合并此定制"调整大小"我在another thread中读到的函数(并没有设置父级),调整小部件本身的大小似乎是可能的,而不需要它在布局中,但现在我面临一个问题,我想要覆盖的按钮保持原来的位置。我希望它做的是在调整大小时跟随一个小部件,但也不一定将它包含在该小部件的布局中(你可以看到我排序一直在试图获得这种效果)
我怎样才能做到这一点?
更新:
所以我设法弄清楚交互式调整大小/缩放是如何工作的。基本上,窗口小部件的位置增加1个像素,具体取决于单个布局中有多少个窗口小部件。所以我试图复制这个效果(我在这个测试布局中有两个小部件,所以理论上它应该为叠加按钮的像素变化3增加一个像素的位置)。它有点工作,但我现在注意到,如果我在拖动时移动鼠标太快,调整大小不会跟上,反过来导致不对齐。我如何处理这个问题......?
from PyQt4 import QtCore, QtGui
import sys
#https://stackoverflow.com/questions/43126721/pyqt-detect-resizing-in-widget-window-resized-signal?rq=1
class Window(QtGui.QWidget):
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('Test UI')
self.setMinimumSize(100, 100)
#self.setMaximumSize(250, 500)
self.oldWidth = 0.0
self.oldHeight = 0.0
self.getOriginalDimensions = False
self.oldButtonPosX = 5.0
self.oldButtonPosY = 5.0
self.resized.connect(self.someFunction)
position = QtGui.QCursor.pos()
self.move(position)
self.uiWidget = QtGui.QWidget()
self.freeWidget = QtGui.QWidget(self.uiWidget)
self.verticalLayout = QtGui.QVBoxLayout(self.freeWidget)
self.exportPushButton = QtGui.QPushButton(self.freeWidget)
self.exportPushButton.setText('ExportV')
self.verticalLayout.addWidget(self.exportPushButton)
self.exportPushButton2 = QtGui.QPushButton(self.freeWidget)
self.exportPushButton2.setText('Export')
self.verticalLayout.addWidget(self.exportPushButton2)
self.testButton = QtGui.QPushButton(self.uiWidget)
self.testButton.setText('.')
self.testButton.setGeometry(5,5,20,20)
#self.testButton = QtGui.QPushButton(self.uiWidget)
self.lyt = QtGui.QVBoxLayout()
self.lyt.addWidget(self.uiWidget)
self.setLayout(self.lyt)
self.buttonYDifference = 0
#self.oldWidth = 100
#self.oldHeight = 100
def resizeEvent(self, event):
self.resized.emit()
#self.oldWidth = self.width()
#self.oldHeight = self.height()
self.oldButtonPosX = self.testButton.x()
self.oldButtonPosY = self.testButton.y()
if self.getOriginalDimensions:
self.oldWidth = self.width()
self.oldHeight = self.height()
return QtGui.QWidget.resizeEvent(self, event)
def someFunction(self):
if not self.getOriginalDimensions:
self.oldWidth = self.width()
self.oldHeight = self.height()
self.getOriginalDimensions = True
newWidth = self.width() - 20.0
newHeight = self.height() - 20.0
self.freeWidget.setGeometry(0,0,newWidth,newHeight)
#newButtonX = self.oldButtonPosX + ((self.width() - self.oldWidth))
yDifference = self.oldHeight - self.height()
print self.buttonYDifference
if self.buttonYDifference <= 3 and self.buttonYDifference >= -3:
if yDifference == 1:
self.buttonYDifference +=1
elif yDifference == -1:
self.buttonYDifference -=1
else:
newButtonY = self.oldButtonPosY - self.buttonYDifference
self.testButton.setGeometry(self.oldButtonPosX,newButtonY,20,20)
self.buttonYDifference = 0
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())