为什么我的 window 大小在加载 UI 后会发生变化?
Why does my window size change after loading my UI?
我正在尝试制作一种类似于 Google 恐龙的游戏。问题是当我启动我的应用程序时,我的 window 的高度在几秒钟后发生变化,所以当我尝试将“恐龙”放在底部时它仍然浮动,因为 [=27= 的高度=] 改变了。
“恐龙”是漂浮的盒子:
这是主要的window
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QFrame
from PyQt5.QtCore import Qt, QTimer, QRect
from PyQt5.QtGui import QPen, QBrush, QPainter
from PyQt5 import uic
import random
class animation(QWidget):
def __init__(self):
super().__init__()
self.shapes = []
self.dimension = 50
#hilo del juego
self.game_timer = QTimer(self)
self.game_timer.timeout.connect(self.animation)
self.game_timer.start(10)
#crear las figuras
self.shapes_generator_timer = QTimer(self)
self.shapes_generator_timer.timeout.connect(self.new_shape)
self.shapes_generator_timer.start(500)
#jugador
coord_x = self.width()
coord_y = self.height() - self.dimension
self.player = QRect(200, coord_y-2, self.dimension, self.dimension)
def new_shape(self):
coord_x = self.width()
coord_y = self.height() - self.dimension
rect = QRect(coord_x, coord_y-2, self.dimension, self.dimension)
self.shapes.append(rect)
def animation(self):
for index,shape in enumerate(self.shapes):
shape.moveLeft(shape.left() - 5)
self.delete_shape(index,shape)
self.update()
print(self.height())
def delete_shape(self, index,shape):
if shape.getCoords()[2] < 0:
del self.shapes[index]
print(len(self.shapes))
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.white,0,Qt.SolidLine))
painter.setBrush(QBrush(Qt.white,Qt.SolidPattern))
painter.drawRect(self.rect())
painter.setPen(QPen(Qt.black,1,Qt.SolidLine))
painter.setBrush(QBrush(Qt.green,Qt.SolidPattern))
for shape in self.shapes:
painter.drawRect(shape)
painter.drawRect(self.player)
ui, _ = uic.loadUiType("PYQT5\interface-animation.ui")
class MyApp(QWidget,ui):
def __init__(self):
super().__init__()
self.setupUi(self)
self.animation = animation()
frame = self.findChild(QFrame, "frame")
layout = QHBoxLayout()
layout.addWidget(self.animation)
frame.setLayout(layout)
app = QApplication(sys.argv)
myApp = MyApp()
myApp.show()
sys.exit(app.exec_())
这是我的 UI 文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1201</width>
<height>638</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="styleSheet">
<string notr="true">background-color:rgb(0,0,0);</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
您不能在实例化过程中依赖小部件的几何形状,除非您指定固定大小:默认情况下,所有 QWidget 类 在初始化期间的大小为 640x480。
在您的情况下,解决方案很简单:在 resizeEvent()
中移动玩家位置的计算,这是每次调整小部件大小时(由系统、用户、或任何 parent/child 布局要求):
def resizeEvent(self, event):
self.player = QRect(200, self.height() - self.dimension-2, self.dimension, self.dimension)
请注意,您的实现并不完全正确,结果是如果 window 在播放时调整大小,障碍物的位置将是错误的,所以我建议另一种方法:始终在 y= 处创建项目0,平移绘画事件中的矩形:
class animation(QWidget):
def __init__(self):
# ...
self.player = QRect(200, <b>0</b>, self.dimension, self.dimension)
def new_shape(self):
coord_x = self.width()
rect = QRect(coord_x, <b>0</b>, self.dimension, self.dimension)
self.shapes.append(rect)
# ...
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.white,0,Qt.SolidLine))
painter.setBrush(QBrush(Qt.white,Qt.SolidPattern))
painter.drawRect(self.rect())
coord_y = self.height() - self.dimension
painter.setPen(QPen(Qt.black,1,Qt.SolidLine))
painter.setBrush(QBrush(Qt.green,Qt.SolidPattern))
for shape in self.shapes:
painter.drawRect(<b>shape.translated(0, coord_y)</b>)
painter.drawRect(<b>self.player.translated(0, coord_y)</b>)
请注意,对使用 uic/pyuic 创建的 UI 使用 findChild
是没有意义的,因为每个小部件的实例属性已经在 setupUi
中创建:您已经可以使用 self.frame
:
访问框架
class MyApp(QWidget,ui):
def __init__(self):
# ...
self.frame.setLayout(layout)
您可能在某些在线教程中发现了这种方法,不幸的是,它们完全错误,并暗示这是一种非常糟糕的做法。
我正在尝试制作一种类似于 Google 恐龙的游戏。问题是当我启动我的应用程序时,我的 window 的高度在几秒钟后发生变化,所以当我尝试将“恐龙”放在底部时它仍然浮动,因为 [=27= 的高度=] 改变了。
“恐龙”是漂浮的盒子:
这是主要的window
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QFrame
from PyQt5.QtCore import Qt, QTimer, QRect
from PyQt5.QtGui import QPen, QBrush, QPainter
from PyQt5 import uic
import random
class animation(QWidget):
def __init__(self):
super().__init__()
self.shapes = []
self.dimension = 50
#hilo del juego
self.game_timer = QTimer(self)
self.game_timer.timeout.connect(self.animation)
self.game_timer.start(10)
#crear las figuras
self.shapes_generator_timer = QTimer(self)
self.shapes_generator_timer.timeout.connect(self.new_shape)
self.shapes_generator_timer.start(500)
#jugador
coord_x = self.width()
coord_y = self.height() - self.dimension
self.player = QRect(200, coord_y-2, self.dimension, self.dimension)
def new_shape(self):
coord_x = self.width()
coord_y = self.height() - self.dimension
rect = QRect(coord_x, coord_y-2, self.dimension, self.dimension)
self.shapes.append(rect)
def animation(self):
for index,shape in enumerate(self.shapes):
shape.moveLeft(shape.left() - 5)
self.delete_shape(index,shape)
self.update()
print(self.height())
def delete_shape(self, index,shape):
if shape.getCoords()[2] < 0:
del self.shapes[index]
print(len(self.shapes))
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.white,0,Qt.SolidLine))
painter.setBrush(QBrush(Qt.white,Qt.SolidPattern))
painter.drawRect(self.rect())
painter.setPen(QPen(Qt.black,1,Qt.SolidLine))
painter.setBrush(QBrush(Qt.green,Qt.SolidPattern))
for shape in self.shapes:
painter.drawRect(shape)
painter.drawRect(self.player)
ui, _ = uic.loadUiType("PYQT5\interface-animation.ui")
class MyApp(QWidget,ui):
def __init__(self):
super().__init__()
self.setupUi(self)
self.animation = animation()
frame = self.findChild(QFrame, "frame")
layout = QHBoxLayout()
layout.addWidget(self.animation)
frame.setLayout(layout)
app = QApplication(sys.argv)
myApp = MyApp()
myApp.show()
sys.exit(app.exec_())
这是我的 UI 文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1201</width>
<height>638</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="styleSheet">
<string notr="true">background-color:rgb(0,0,0);</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
您不能在实例化过程中依赖小部件的几何形状,除非您指定固定大小:默认情况下,所有 QWidget 类 在初始化期间的大小为 640x480。
在您的情况下,解决方案很简单:在 resizeEvent()
中移动玩家位置的计算,这是每次调整小部件大小时(由系统、用户、或任何 parent/child 布局要求):
def resizeEvent(self, event):
self.player = QRect(200, self.height() - self.dimension-2, self.dimension, self.dimension)
请注意,您的实现并不完全正确,结果是如果 window 在播放时调整大小,障碍物的位置将是错误的,所以我建议另一种方法:始终在 y= 处创建项目0,平移绘画事件中的矩形:
class animation(QWidget):
def __init__(self):
# ...
self.player = QRect(200, <b>0</b>, self.dimension, self.dimension)
def new_shape(self):
coord_x = self.width()
rect = QRect(coord_x, <b>0</b>, self.dimension, self.dimension)
self.shapes.append(rect)
# ...
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.white,0,Qt.SolidLine))
painter.setBrush(QBrush(Qt.white,Qt.SolidPattern))
painter.drawRect(self.rect())
coord_y = self.height() - self.dimension
painter.setPen(QPen(Qt.black,1,Qt.SolidLine))
painter.setBrush(QBrush(Qt.green,Qt.SolidPattern))
for shape in self.shapes:
painter.drawRect(<b>shape.translated(0, coord_y)</b>)
painter.drawRect(<b>self.player.translated(0, coord_y)</b>)
请注意,对使用 uic/pyuic 创建的 UI 使用 findChild
是没有意义的,因为每个小部件的实例属性已经在 setupUi
中创建:您已经可以使用 self.frame
:
class MyApp(QWidget,ui):
def __init__(self):
# ...
self.frame.setLayout(layout)
您可能在某些在线教程中发现了这种方法,不幸的是,它们完全错误,并暗示这是一种非常糟糕的做法。