QLabel ведет себя странно на QMainWindow

Я хочу создать графический интерфейс с Qlabel, где будет отображаться изображение, после этого я хочу сделать выбор (прямоугольник) на изображении и сохранить выбор как другое изображение на моем компьютере. Но у меня проблема:

Во-первых, когда я создаю графический интерфейс (без QtDesigner), все работает нормально, но когда я создаю графический интерфейс в QtDesigner, и я хочу отобразить свое новое изображение и класс KpeWindow на метке моего окна, но он отображается в верхнем левом углу, почему?

графический интерфейс:

<?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

QLabel ведет себя странно на QMainWindow

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:

QLabel ведет себя странно на QMainWindow

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_())

поделитесь своим gui.ui. Как вы хотите, чтобы он отображался в QMainWindow? Как вы хотите, чтобы KpeWindow отображался в QMainWindow?

eyllanesc 29.05.2019 07:58

@eyllanesc Я добавляю gui.ui, я хочу отобразить свое изображение в поле с ярлыком и сделать выбор на нем, чтобы сохранить выбор как новое изображение.

Vesa95 29.05.2019 08:03
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
288
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина ошибки заключается в том, что вы предполагаете, что если вы создадите виджет с тем же именем, что и QLabel, он заменит его, но это неверно, вы создаете другой QLabel, родительским элементом которого является окно, поэтому он будет расположен в верхний левый.

Итак, есть 2 решения:

  1. Продвигайте KpeWindow как графику, пример есть в этот ответ.

  2. Установите KpeWindow в QLabel через макет.

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_())

Второе решение самое простое.

Работал как шарм! Большое спасибо!

Vesa95 29.05.2019 08:24

Другие вопросы по теме