How to integrate Pygame and PyQt4?

Question:

I’m using python 2.7 and Ubuntu 14.04.

I’m trying to do this in order to have my pygame window inside my GUI

On some platforms it is possible to embed the pygame display into an already existing window. To do this, the environment variable SDL_WINDOWID must be set to a string containing the window id or handle. The environment variable is checked when the pygame display is initialized

So this is what I did:

from PyQt4 import QtGui, QtCore
import os
import subprocess
import sys

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
    MainWindow.setWindowModality(QtCore.Qt.ApplicationModal)
    MainWindow.setFixedSize(800, 600)
    QtCore.QMetaObject.connectSlotsByName(MainWindow)
    self.iniMap()

def iniMap(self):
    command = "xprop -root _NET_ACTIVE_WINDOW"
    output = subprocess.Popen(["/bin/bash", "-c", command], stdout=subprocess.PIPE)
    activeWindowID = str(output.communicate()[0].decode("utf-8").strip().split()[-1])
    os.environ['SDL_WINDOWID'] = activeWindowID
    import pygame
    pygame.init()
    screen = pygame.display.set_mode((565, 437), pygame.NOFRAME)

class frmMain(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(frmMain, self).__init__(parent, flags=QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setupUi(self)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    form = frmMain()
    form.show()
    sys.exit(app.exec_())

But it doesn’t work. It only shows my PyQt window. I don’t know whether I’m doing something wrong or pygame just cannot be integrated with PyQt

What should I do to get my pygame window embedded in frmMain?

Thank you in advance.

Asked By: Pablo Ladreyt

||

Answers:

Here is a sample solution as per the comment above:

from PyQt4 import QtGui
import pygame
import sys

class ImageWidget(QtGui.QWidget):
    def __init__(self,surface,parent=None):
        super(ImageWidget,self).__init__(parent)
        w=surface.get_width()
        h=surface.get_height()
        self.data=surface.get_buffer().raw
        self.image=QtGui.QImage(self.data,w,h,QtGui.QImage.Format_RGB32)

    def paintEvent(self,event):
        qp=QtGui.QPainter()
        qp.begin(self)
        qp.drawImage(0,0,self.image)
        qp.end()


class MainWindow(QtGui.QMainWindow):
    def __init__(self,surface,parent=None):
        super(MainWindow,self).__init__(parent)
        self.setCentralWidget(ImageWidget(surface))



pygame.init()
s=pygame.Surface((640,480))
s.fill((64,128,192,224))
pygame.draw.circle(s,(255,255,255,255),(100,100),50)

app=QtGui.QApplication(sys.argv)
w=MainWindow(s)
w.show()
app.exec_()
Answered By: Photon

Not enough reputation to comment on Photon‘s answer, but I just wanted to note that with PyQt6, the QImage formats are now invoked like this:

QtGui.QImage.Format.Format_RGB32

Credit to F.R.D for pointing this out in another answer here.

Answered By: Andrew L