0

The goal is to draw a line (like in MS paint) using OpenGL and Pyqt5. The problem is all i get is a black window. If something like glRectf(20,20,-20,20) is written in paintGL() it shows up correct. code -

from OpenGL.GL import *
from PyQt5.QtOpenGL import *
from PyQt5.QtCore import QTimer

a = b = None

class Coordinate():

    def __init__(self,x,y):
        self.x = x/2 -200           # mapping x [0,800] to [-200,200]
        self.y = -2*y/3 + 200       # mapping y [0,600] to [200,-200]

    def getx(self):
        return self.x

    def gety(self):
        return self.y

class GlWindow(QGLWidget):

    def __init__(self):
        print("Entering GL")
        super(GlWindow,self).__init__()
        self.setAutoBufferSwap(True)
        # timer = QTimer()
        # timer.timeout.connect(self.update)
        # timer.start(10)

    def mousePressEvent(self,e):
        a = Coordinate(e.x(),e.y())
        print(a.getx(),a.gety())

    def mouseMoveEvent(self,e):
        b = Coordinate(e.x(),e.y())
        print(b.getx(),b.gety())
        self.updateGL()

    def mouseReleaseEvent(self,e):
        b = Coordinate(e.x(),e.y())
        print(b.getx(),b.gety())
        self.updateGL()

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glColor3f(0.0,0.0,1.0)
        if a and b is not None:
            print("Drawing line")
            glBegin(GL_LINES)
            glVertex2f(a.getx(),a.gety())
            glVertex2f(b.getx(),b.gety())
            glEnd()

    def resizeGL(self, w, h):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(-200, 200, -200, 200, -200.0, 200.0)
        glViewport(0, 0, w, h)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def initializeGL(self):
        glClearColor(0.10, 0.10, 0.10, 1.0) # Grey
        glClearDepth(1.0)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LEQUAL)
        glShadeModel(GL_SMOOTH)

Stdout -

   Entering GL
   66.5 40.0
   66.5 40.0
   66.5 40.66666666666666
   67.0 40.66666666666666
   67.5 40.66666666666666
   69.0 42.0
   70.5 42.66666666666666
   72.5 44.66666666666666
   74.0 46.0
   75.5 46.66666666666666
   76.5 48.0
   77.5 48.66666666666666
   78.5 49.33333333333334
   79.0 49.33333333333334
   79.0 49.33333333333334
   79.5 49.33333333333334
   79.5 49.33333333333334
   79.5 49.33333333333334

The GlWindow() instance is created in another widget (MainWindow : QMainWindow, for menubar) and set as central Widget. I tried Qtimer and update(), it did not work.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • And you're 100% sure `resizeGL` always gets called at least once before `paintGL`? – genpfault Oct 19 '17 at 16:30
  • Yes , well what i did was i added 2 print statements ( "In resizeGL", "In paintGL") and both were printed. Moreover everytime the mousevent occurs, "In paintGL" statement is printed. So updateGL is working ? Sorry I am a newbie :) – Nishad Wadwekar Oct 19 '17 at 17:04
  • [This answer](https://stackoverflow.com/a/46259752/2588654) that I wrote here should draw a triangle to the screen in a PyQt4 (rather than 5) window. The only thing that seems odd is why go through all of the trouble of mapping your coordinates to that odd `glOrtho` matrix instead of taking advantage of the width and height? I have a feeling that the drawing is happening, but maybe the lines are not being drawn in the view of your window. – CodeSurgeon Oct 19 '17 at 17:14
  • I get what you are saying but as i said when i write glRectf(-50,50,50,50) , i get a rectangle right in the centre of the window and my stdout is in the same range. Also since paintGL() is being called after mouse event through updateGL() i never get "Drawing line" in stdout (please refer code ) but a and b values are printed so they cannot be None. As of mapping its a requirement for the project i am doing and since Qt (0,0) is top left and openGL (0,0) is bottom left i still would have to map it – Nishad Wadwekar Oct 20 '17 at 05:18

1 Answers1

0

The problem is with the the global variables a and b. They are not being updated in the mouse event callbacks. Try using global a and global b statements in your callbacks.

A better approach would be to make these variables as class attributes and update them as self.a = #whatever.