QGraphicsView не отображает QGraphicsItems

Использование PyQt4.

Моя цель - загрузить «части» .png, назначить их QGraphicsItems, добавить их на сцену и отобразить их в QGraphicsView. (Прямо сейчас меня не волнуют их координаты, все, что меня волнует, это заставить эту чертову штуку работать).

В настоящее время ничего не отображается. Сначала я подумал, что это проблема с добавлением элементов и отсутствием обновления QGraphicsView, но, почитав немного больше о видовых экранах, это не имело смысла. Поэтому я протестировал добавление элементов QGraphicsView еще до того, как настроил вид (поэтому я знаю, что это не будет проблемой обновления), и он по-прежнему ничего не отображал. Путь однозначно правильный. Вот код, который показывает, что происходит...

Игнорировать проблемы с пробелами, макет перепутался при вставке

class MainWindow(QtGui.QMainWindow):
 def __init__(self, parent = None):
  QtGui.QMainWindow.__init__(self, parent)

  self.setWindowTitle('NT State Editor')

  winWidth = 1024
  winHeight = 768

  screen = QtGui.QDesktopWidget().availableGeometry()
  screenCenterX = (screen.width() - winWidth) / 2
  screenCenterY = (screen.height() - winHeight) / 2
  self.setGeometry(screenCenterX, screenCenterY, winWidth, winHeight)

  self.tileMap = tilemap.TileMap()
  self.tileBar = tilebar.TileBar()

  mapView = QtGui.QGraphicsView(self.tileMap)
  tileBarView = QtGui.QGraphicsView(self.tileBar)

  button = tilebar.LoadTilesButton()
  QtCore.QObject.connect(button, QtCore.SIGNAL('selectedFile'),
      self.tileBar.loadTiles)

  hbox = QtGui.QHBoxLayout()
  hbox.addWidget(mapView)
  hbox.addWidget(self.tileBarView)
  hbox.addWidget(button)

  mainWidget = QtGui.QWidget()
  mainWidget.setLayout(hbox)

  self.setCentralWidget(mainWidget)


 app = QtGui.QApplication(sys.argv)
 mainWindow = MainWindow()
 mainWindow.show()
 sys.exit(app.exec_())

--

class Tile(QtGui.QGraphicsPixmapItem):
    def __init__(self, parent = None):
        QtGui.QGraphicsPixmapItem(self, parent)
        self.idAttr = -1


class TileBar(QtGui.QGraphicsScene):
    def __init__(self, parent = None):
    QtGui.QGraphicsScene.__init__(self, parent)

    def loadTiles(self, filename):
    tree = ElementTree()
    tree.parse(filename)
    root = tree.getroot()

    sheets = root.findall('sheet')

    for sheet in sheets:
        sheetPath = sheet.get('path')
        sheetImg = QtGui.QImage(sheetPath)

        strips = sheet.findall('strip')
        for strip in strips:
            tile = Tile()
            tile.idAttr = strip.get('id')

            clip = strip.find('clip')
            x = clip.get('x')
            y = clip.get('y')
            width = clip.get('width')
            height = clip.get('height')

            subImg = sheetImg.copy(int(x), int(y), int(width), int(height))
            pixmap = QtGui.QPixmap.fromImage(subImg)
            tile.setPixmap(pixmap)

            self.addItem(tile)

Я пробовал кое-что с подключением сигнала «changed()» TileBar к различным функциям «представления», но ни одна из них не сработала. У меня были некоторые проблемы с поиском хороших примеров способов использования Graphics View Framework (большинство из них очень и очень мелкие), поэтому дайте мне знать, если я делаю это совершенно неправильно.

Любая помощь приветствуется. Спасибо.


person random    schedule 10.09.2010    source источник


Ответы (1)


Довольно сложно сказать, что не так с вашим кодом, так как он не завершен и отсутствуют некоторые части для его компиляции. Хотя есть несколько мест, которые потенциально могут вызвать проблему:

  1. Ваш конструктор класса Title; Я считаю, что вы должны вызвать конструктор базового класса, выполнив: QtGui.QGraphicsPixmapItem.__init__(self, parent).
  2. Похоже, объекты вашей графической сцены создаются в сигнале нажатия кнопки. Могут быть проблемы с подключением вашего сигнала к соответствующему слоту, вы должны увидеть предупреждения в выводе, если в вашем виджете есть такие проблемы.
  3. Похоже, вы загружаете имена файлов изображений из файла xml, довольно сложно проверить, логика там прямая, но потенциально у вас тоже может быть проблема.

Ниже приведена упрощенная версия вашего кода, который загружает изображение ab в заголовок и добавляет его в графическую сцену:

import sys
from PyQt4 import QtGui, QtCore

class Tile(QtGui.QGraphicsPixmapItem):
    def __init__(self, parent=None):
        QtGui.QGraphicsPixmapItem.__init__(self, parent)
        self.idAttr = -1

class TileBar(QtGui.QGraphicsScene):
    def __init__(self, parent=None):
        QtGui.QGraphicsScene.__init__(self, parent)

    #def loadTiles(self, filename):
    def loadTiles(self):

        sheetImg = QtGui.QImage("put_your_file_name_here.png")
        pixmap = QtGui.QPixmap.fromImage(sheetImg)

        tile = Tile()
        tile.setPixmap(pixmap)

        self.addItem(tile)

        # skipping your ElementTree parsing logic here

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)

        self.setWindowTitle('NT State Editor')

        winWidth = 1024
        winHeight = 768

        screen = QtGui.QDesktopWidget().availableGeometry()
        screenCenterX = (screen.width() - winWidth) / 2
        screenCenterY = (screen.height() - winHeight) / 2
        self.setGeometry(screenCenterX, screenCenterY, winWidth, winHeight)

        #self.tileMap = Tiletilebar.Map()
        self.tileBar = TileBar()

        #mapView = QtGui.QGraphicsView(self.tileMap)
        self.tileBarView = QtGui.QGraphicsView(self.tileBar)

        #button = self.tilebar.LoadTilesButton()
        button = QtGui.QPushButton() 
        QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), 
                               self.tileBar.loadTiles)

        #self.tileBar.loadTiles('some_file_name')

        hbox = QtGui.QHBoxLayout()
        #hbox.addWidget(mapView)
        hbox.addWidget(self.tileBarView)
        hbox.addWidget(button)

        mainWidget = QtGui.QWidget()
        mainWidget.setLayout(hbox)

        self.setCentralWidget(mainWidget)

app = QtGui.QApplication([])
exm = MainWindow()
exm.show()
app.exec_()

надеюсь, это поможет, с уважением

person serge_gubenko    schedule 11.09.2010
comment
Вы были правы в конструкторе, я тоже это заметил. Однако проблема была на самом деле в получении подизображения, по какой-то причине преобразование в int не работает. Исправляем прямо сейчас. - person random; 11.09.2010
comment
Да, проблема была в файле xml, потому что путь был относительным. - person random; 11.09.2010