我想创建一个带有Qlabel的gui来显示图像,此后,我要在图像上进行选择(矩形)并将该选择另存为我的计算机中的另一幅图像。但是我有一个问题:
首先,当我创建GUI(没有QtDesigner)时,一切正常,但是当我在QtDesigner上创建GUI时,我想在框标签上显示我的新图像和KpeWindow类,但它显示在左上角,为什么?
gui.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GUI</class>
<widget class="QMainWindow" name="GUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>770</width>
<height>527</height>
</rect>
</property>
<property name="windowTitle">
<string>GUI</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="clear_btn">
<property name="geometry">
<rect>
<x>10</x>
<y>220</y>
<width>71</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>clear</string>
</property>
</widget>
<widget class="QPushButton" name="save_btn">
<property name="geometry">
<rect>
<x>70</x>
<y>220</y>
<width>69</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>save</string>
</property>
</widget>
<widget class="QPushButton" name="load_btn">
<property name="geometry">
<rect>
<x>130</x>
<y>220</y>
<width>67</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>load</string>
</property>
</widget>
<widget class="QLabel" name="grafic">
<property name="geometry">
<rect>
<x>218</x>
<y>12</y>
<width>531</width>
<height>411</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>770</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
代码的第一部分:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi
class KpeWindow(QtWidgets.QLabel):
def __init__(self, parent=None):
QtWidgets.QLabel.__init__(self,parent)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
position = QtCore.QPoint(event.pos())
if self.selection.isVisible():
# visible selection
print(self.upper_left.manhattanLength())
if (self.upper_left - position).manhattanLength() < 20:
# close to upper left corner, drag it
self.mode = "drag_upper_left"
elif (self.lower_right - position).manhattanLength() < 20:
# close to lower right corner, drag it
self.mode = "drag_lower_right"
else:
# clicked somewhere else, hide selection
self.selection.hide()
else:
# no visible selection, start new selection
self.upper_left = position
self.lower_right = position
self.mode = "drag_lower_right"
self.selection.show()
def mouseMoveEvent(self, event):
'''
Mouse moved. If selection is visible, drag it according to drag mode.
'''
if self.selection.isVisible():
# visible selection
if self.mode is "drag_lower_right":
self.lower_right = QtCore.QPoint(event.pos())
# print(str(self.lower_right))
elif self.mode is "drag_upper_left":
self.upper_left = QtCore.QPoint(event.pos())
# print(str(self.upper_left))
# update geometry
self.selection.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())
没有QtDesigner的MainWindow
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
QtWidgets.QMainWindow.__init__(self)
layout = QtWidgets.QVBoxLayout(self)
label = KpeWindow(self)
pixmap = QPixmap("image.JPG")
label.setPixmap(pixmap)
layout.addWidget(label)
label.setFocusPolicy(Qt.StrongFocus)
self.setFocusProxy(label)
label.setFocus(True)
self.setLayout(layout)
self.setFixedSize(640, 480)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
使用QtDesigner的MainWindow:
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi('GUI/gui.ui', self)
#self.grafic <-- this is the box label
self.grafic = KpeWindow(self)
pixmap = QPixmap("image.JPG")
self.grafic.setPixmap(pixmap)
self.grafic.setFocusPolicy(Qt.StrongFocus)
self.setFocusProxy(self.grafic)
self.grafic.setFocus(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
答案 0 :(得分:2)
错误的原因是,您假设如果创建一个具有与QLabel相同名称的小部件,它将替换它,但这是错误的,您正在创建另一个QLabel,其父级是窗口,因此它将位于topLeft中。
所以有2种解决方案:
提升KpeWindow的外观,this answer中有一个示例。
通过布局在QLabel中设置KpeWindow。
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class KpeWindow(QtWidgets.QLabel):
# ...
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('GUI/gui.ui', self)
kpe_window = KpeWindow()
pixmap = QtGui.QPixmap("image.JPG")
kpe_window.setPixmap(pixmap)
kpe_window.setFocusPolicy(QtCore.Qt.StrongFocus)
self.setFocusProxy(kpe_window)
kpe_window.setFocus(True)
lay = QtWidgets.QVBoxLayout(self.grafic)
lay.addWidget(kpe_window)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
第二种解决方案是最简单的。