Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. how to dynamically create 2 to 4 QTimers based on attributes in a json file

how to dynamically create 2 to 4 QTimers based on attributes in a json file

Scheduled Pinned Locked Moved Unsolved Qt for Python
13 Posts 6 Posters 830 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H htjane

    Hi all
    I'm creating a pyQt5 window to show several boards one after another for displaying shapes for users to click one target shape on each board.

    My question is how to dynamically create 2 to 4 QTimers for shapes based on the "entry_time" attributes in a loaded json file. I also want to start QTimers simultaneously and link them with timeout events.

    Each shape has its own entryTimer AND exitTimer. For example I have 2 boards. The entryTimer is started at the same time for all shapes on both board 1 AND 2. The entrytime value for shapes on board 2 has a value higher than board 1 entrytime + duaration. (duration indicates the time (in seconds) that the shapes appear.)
    So if there are 16 shapes, and 2 boards, there will be a total of 32 entrytimes. The first 16 entrytimes are defined by the entrytime for board_1 and the second 16 entrytimes are defined by the entrytime for board_2 . The second 16 entrytimes values will be higher than the first 16 entrytimes + duration so these shapes only appear after the first 16 shapes are cleared by the exitTimer.

    The exitTimer is started at the same time for all shapes on the SAME board. When it times out, the clearboard() method removes all shapes to make room for shapes on the next board. Additionally, if a user correctly clicks the target shape before the duration expires, the clearboard() method is also called. It updates the next board entrytime to 0.5 seconds for the shapes that appear on the following board to prevent waiting for the remainder of the duration to expire.

    For example, if the duration is set to 60 seconds and a user correctly clicks the target shape in 3 seconds. The clearboard() resets the entrytime to 0.5 seconds to prevent any delays for the shape appearing on the following board.

    Note: clearboard() only reset timers without actually manipulating shapes

    The JSON file may contain 2 to 4 boards, each with its own entry_time attribute applicable to all shapes on the board. Any help is appreciated!
    0a1eaf41-2e67-46a0-84fd-878998fd86fa-image.png

    class MyApp(QMainWindow):
       def __init__(self):
            # some Initialization for the main window 
            self.ui.NextButton.clicked.connect(self.showPage1)
       def showPage1(self):
            file = QFile("./practice_scripts/OUCH_0_1_1_2.json")
            file.open(QFile.ReadOnly | QFile.Text)
            if file.isOpen():
                data = file.readAll()
                qjson = self.jsonParse(data)
                self.ui.startBtn.clicked.connect(lambda: self.showTrial1(qjson))
       def showTrial1(self, qjson):
            #Trial1 has two boards
            boards = qjson["boards"].toArray()
            timerList = []
            for b in boards:
                board = b.toObject()
                timerList.append(board["entry_time"].toDouble())
            for t in timerList:
            #currently I store entry_time into a list and create a QTimer for each item in the list, but I don't know how to start them at the same time and if I need to use threads
                boardEntrytimer = QTimer(self)
                print("BoardEntrytimer Started at  " + getTimestamp())
                boardEntrytimer.singleShot(int(t), self.updateBoard(board))
        def updateBoard(self, board):
            print("updated!  " + getTimestamp())
            bd = Board(board)
    class Board(QWidget):
        def __init__(self, board, parent=None):
            #some initialization of the board
           self.entry_time = board["entry_time"].toInt()
           self.Entrytimer = QTimer(self)
           self.Entrytimer.singleShot(self.entry_time * 1000, self.drawShapes)
           self.Exittimer = QTimer(self)
           print("prepare to clear board  ~ 20s " + getTimestamp())
           self.Exittimer.singleShot(self.duration * 1000, self.clearBoard)
        def drawShapes(self):
        # code to draw shapes on a board
        def clearBoard(self):
        #  code to clear shapes on a board
    
    enjoysmathE Offline
    enjoysmathE Offline
    enjoysmath
    wrote on last edited by
    #3

    @htjane

    Be careful creating signal/slot connections in a Loop. At least in PyQt5 I always ran into the bug where all were connected to the last slot or something. Solved by more explicit lambda function capture parameters or something.

    There's a 95% chance you'll also hit this bug.

    https://github.com/enjoysmath
    https://math.stackexchange.com/users/26327/exercisingmathematician

    jeremy_kJ 1 Reply Last reply
    0
    • H Offline
      H Offline
      htjane
      wrote on last edited by htjane
      #4

      Thank you both @SGaist and @enjoysmath !
      I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
      Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

      Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

          def showTrial1(self, qjson):
              self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
              rulesets = qjson["rulesets"].toObject()
              boardArr = qjson["boards"].toArray()
              for b in boardArr:
                  board = b.toObject()
                  bd = Board(rulesets, board, self.geometry())
                  self.boards.append(bd)
                  self.ui.stackedWidget.addWidget(bd)
                  
              for bd in self.boards:
                  boardEntrytimer = QTimer(self)
                  boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = bd: self.createBoard(arg))
      
          def createBoard(self,board):
              # print("updated!  " + getTimestamp())
             self.ui.stackedWidget.setCurrentWidget(board)
      
      enjoysmathE jeremy_kJ 4 Replies Last reply
      1
      • H htjane

        Thank you both @SGaist and @enjoysmath !
        I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
        Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

        Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

            def showTrial1(self, qjson):
                self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                rulesets = qjson["rulesets"].toObject()
                boardArr = qjson["boards"].toArray()
                for b in boardArr:
                    board = b.toObject()
                    bd = Board(rulesets, board, self.geometry())
                    self.boards.append(bd)
                    self.ui.stackedWidget.addWidget(bd)
                    
                for bd in self.boards:
                    boardEntrytimer = QTimer(self)
                    boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = bd: self.createBoard(arg))
        
            def createBoard(self,board):
                # print("updated!  " + getTimestamp())
               self.ui.stackedWidget.setCurrentWidget(board)
        
        enjoysmathE Offline
        enjoysmathE Offline
        enjoysmath
        wrote on last edited by
        #5

        @htjane https://stackoverflow.com/a/7546960/7076615

        https://github.com/enjoysmath
        https://math.stackexchange.com/users/26327/exercisingmathematician

        1 Reply Last reply
        0
        • H htjane

          Thank you both @SGaist and @enjoysmath !
          I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
          Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

          Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

              def showTrial1(self, qjson):
                  self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                  rulesets = qjson["rulesets"].toObject()
                  boardArr = qjson["boards"].toArray()
                  for b in boardArr:
                      board = b.toObject()
                      bd = Board(rulesets, board, self.geometry())
                      self.boards.append(bd)
                      self.ui.stackedWidget.addWidget(bd)
                      
                  for bd in self.boards:
                      boardEntrytimer = QTimer(self)
                      boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = bd: self.createBoard(arg))
          
              def createBoard(self,board):
                  # print("updated!  " + getTimestamp())
                 self.ui.stackedWidget.setCurrentWidget(board)
          
          enjoysmathE Offline
          enjoysmathE Offline
          enjoysmath
          wrote on last edited by
          #6

          @htjane I think ๐Ÿ’ญthat u're already doing it correctly โœ”. However, please tell us more about your bug. ๐Ÿ›

          https://github.com/enjoysmath
          https://math.stackexchange.com/users/26327/exercisingmathematician

          1 Reply Last reply
          0
          • H htjane

            Thank you both @SGaist and @enjoysmath !
            I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
            Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

            Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

                def showTrial1(self, qjson):
                    self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                    rulesets = qjson["rulesets"].toObject()
                    boardArr = qjson["boards"].toArray()
                    for b in boardArr:
                        board = b.toObject()
                        bd = Board(rulesets, board, self.geometry())
                        self.boards.append(bd)
                        self.ui.stackedWidget.addWidget(bd)
                        
                    for bd in self.boards:
                        boardEntrytimer = QTimer(self)
                        boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = bd: self.createBoard(arg))
            
                def createBoard(self,board):
                    # print("updated!  " + getTimestamp())
                   self.ui.stackedWidget.setCurrentWidget(board)
            
            enjoysmathE Offline
            enjoysmathE Offline
            enjoysmath
            wrote on last edited by
            #7

            @htjane Oh I see, you've already solved it. Told you 95% chance.

            https://github.com/enjoysmath
            https://math.stackexchange.com/users/26327/exercisingmathematician

            1 Reply Last reply
            0
            • enjoysmathE enjoysmath

              @htjane

              Be careful creating signal/slot connections in a Loop. At least in PyQt5 I always ran into the bug where all were connected to the last slot or something. Solved by more explicit lambda function capture parameters or something.

              There's a 95% chance you'll also hit this bug.

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by jeremy_k
              #8

              @enjoysmath said in how to dynamically create 2 to 4 QTimers based on attributes in a json file:

              @htjane

              Be careful creating signal/slot connections in a Loop. At least in PyQt5 I always ran into the bug where all were connected to the last slot or something. Solved by more explicit lambda function capture parameters or something.

              That's unrelated to PyQt, and not a bug. Captures bind to variables, not the value they hold at the time of capture.

              i = 0
              function = lambda: print(i)
              i = 1
              function()
              

              Output:

              1
              

              Asking a question about code? http://eel.is/iso-c++/testcase/

              JonBJ 1 Reply Last reply
              1
              • H htjane

                Thank you both @SGaist and @enjoysmath !
                I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
                Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

                Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

                    def showTrial1(self, qjson):
                        self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                        rulesets = qjson["rulesets"].toObject()
                        boardArr = qjson["boards"].toArray()
                        for b in boardArr:
                            board = b.toObject()
                            bd = Board(rulesets, board, self.geometry())
                            self.boards.append(bd)
                            self.ui.stackedWidget.addWidget(bd)
                            
                        for bd in self.boards:
                            boardEntrytimer = QTimer(self)
                            boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = bd: self.createBoard(arg))
                
                    def createBoard(self,board):
                        # print("updated!  " + getTimestamp())
                       self.ui.stackedWidget.setCurrentWidget(board)
                
                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on last edited by
                #9

                @htjane said in how to dynamically create 2 to 4 QTimers based on attributes in a json file:

                Thank you both @SGaist and @enjoysmath !
                I restructured code as SGaist suggested, created a list of boards and iterated over the board list.
                Like enjoysmath said, I also encountered the issue of only the last board was updated in the singleShot() method. Using a lambda function and grab argument fixed the issue.

                Seems like for entry timers I have a working solution now at least on my machine. Below is my code if anyone would like to take a look: Note that it is not a Minimal, Reproducible Example because my app includes some other functions and event handlers.

                        for bd in self.boards:
                            boardEntrytimer = QTimer(self)
                            boardEntrytimer.singleShot(int(bd.entry_time)*1000, lambda arg = > ```
                

                This code creates an extra QTimer on each loop iteration. QTimer.singleShot() is a static function.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                1 Reply Last reply
                1
                • jeremy_kJ jeremy_k

                  @enjoysmath said in how to dynamically create 2 to 4 QTimers based on attributes in a json file:

                  @htjane

                  Be careful creating signal/slot connections in a Loop. At least in PyQt5 I always ran into the bug where all were connected to the last slot or something. Solved by more explicit lambda function capture parameters or something.

                  That's unrelated to PyQt, and not a bug. Captures bind to variables, not the value they hold at the time of capture.

                  i = 0
                  function = lambda: print(i)
                  i = 1
                  function()
                  

                  Output:

                  1
                  
                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #10

                  @jeremy_k said in how to dynamically create 2 to 4 QTimers based on attributes in a json file:

                  That's unrelated to PyQt, and not a bug.

                  @enjoysmath will be thinking of is the way Python (nothing to do with PyQt, and agreed not a "bug") works for the following pattern:

                  for i in range(10):
                      list_of_buttons[i].clicked.connect(lambda: print(i))
                  

                  I and others started out writing this (posts in this forum and stackoverflow), expecting it have the lambda-slot tell us which button was clicked. Like:

                  for (int i = 0; i < 10; i++)
                      connect(this, list_of_buttons[i], [i]() { qDebug() << i; });
                  

                  which is what people expect it to do.

                  I guess Python passes something like &i would do in C++. The Python user needs:

                      list_of_buttons[i].clicked.connect(lambda ii=i: print(ii))
                  

                  which people do not realise at first, and I imagine @enjoysmath has this in mind.

                  1 Reply Last reply
                  1
                  • H Offline
                    H Offline
                    htjane
                    wrote on last edited by
                    #11

                    Hi all,
                    Sorry I'm new to Qt. Here again asking a follow-up question about reading board instance attributes that have just been modified by keypress event. Not sure if I should post it here or open a new thread. Please Lmk.

                    My question is in the KeyPressEvent of Board class, I set the self.finish attribute to True to indicate the target shape has been clicked and a key pressed, then in MyApp class I want to get the finish attribute of board instance using an if-condition to check if the board has been finished. But the code in MyApp executes before "finish" has been modified by KeyPressEvent, without hanging or waiting for it and "finish" is False whenever I print it in MyApp class. Specifically, I want to read "finish" of each board in MyApp and if it's True, set the entry_time of the next board to 0.5s to prevent waiting this board's duration to expire. Could you guys suggest some solutions?

                    class MyApp(QMainWindow):
                    # constructor and some functions...
                      def showTrial1(self, qjson):
                            self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                    
                            rulesets = qjson["rulesets"].toObject()
                            boardArr = qjson["boards"].toArray()
                    
                            for b in boardArr:  # create boards
                                board = b.toObject()
                                bd = Board(rulesets, board, self.geometry())
                                self.boards.append(bd)
                                self.ui.stackedWidget.addWidget(bd)
                    
                            for bd in self.boards:
                                #call a static timer to draw board based on entry_time
                                QTimer.singleShot(int(bd.entry_time) * 1000, lambda arg=bd: self.createBoard(arg))
                    
                        def createBoard(self, board):
                            board.drawShapes()
                            self.ui.stackedWidget.setCurrentWidget(board)
                    
                    class Board(QWidget):
                        def __init__(self, rulesets, board, size, parent=None):
                            super().__init__(parent)
                            self.rules = rulesets
                            self.lastLeftPoint = QPoint(0, 0)
                            self.id = board["id"].toInt()
                            self.duration = 10  # board["duration"]
                            self.entry_time = board["entry_time"].toDouble()
                            self.stimuli = board["stimuli"]
                            self.shapes = []
                            self.click = False
                            self.boardSize = size
                            self.timeout = False
                            self.finish = False
                    
                        def drawShapes(self):
                            stiArr = self.stimuli.toArray()
                    
                            for s in stiArr:
                    
                                stimuli = s.toObject()
                    
                                ID = stimuli["id"].toInt()
                                # print(ID)
                                color = QtGui.QColor(stimuli["color"].toObject()["color"].toString())
                                text = stimuli["text"].toString()
                                x = math.floor(
                                    stimuli[
                                        "column"].toInt() * self.boardSize.width() / 12.0 - self.boardSize.width() / 24.0)  # 3862 * 2122
                                y = math.floor(stimuli["row"].toInt() * self.boardSize.height() / 12.0 - self.boardSize.height() / 24.0)
                                pos = QtCore.QPoint(x, y)
                                target = stimuli["target"]
                                response = stimuli["response"]
                                # hue = clr["hue"].toInt()
                                # saturation = clr["saturation"].toInt() * 255
                                # value = clr["value"].toInt() * 255
                                # alpha = clr["alpha"].toInt() * 255
                                if stimuli["shape"] == "circle":
                                    self.shapes.append(Circle(ID, 30, pos, color, text, target, response))
                                elif stimuli["shape"] == "cross":
                                    self.shapes.append(Cross(ID, 30, pos, color, text, target, response))
                                elif stimuli["shape"] == "star":
                                    self.shapes.append(Star(ID, 30, pos, color, text, target, response))
                                elif stimuli["shape"] == "hexagon":
                                    self.shapes.append(Hexagon(ID, 30, pos, color, text, target, response))
                                elif stimuli["shape"] == "octagon":
                                    self.shapes.append(Octagon(ID, 30, pos, color, text, target, response))
                                elif stimuli["shape"] == "pentagon":
                                    self.shapes.append(Pentagon(ID, 30, pos, color, text, target, response))
                            # self.update()
                    
                        def paintEvent(self, event):
                            painter = QPainter(self)
                            painter.setRenderHint(QPainter.Antialiasing)
                            if self.timeout:
                                print("cleared!  " + getTimestamp())
                                painter.eraseRect(0, 0, self.boardSize.width(), self.boardSize.height())
                                return
                            for shape in self.shapes:
                                shape.paint(painter)
                            if self.click:
                                painter.setPen(QPen(QColor("green"), 4, Qt.SolidLine))
                                painter.drawRect(self.lastLeftPoint.x() - 15, self.lastLeftPoint.y() - 15, 30, 30)
                                painter.end()
                    
                        def mousePressEvent(self, event):
                            # on left mouse click, it returns the coordinates
                            if event.button() == Qt.LeftButton:
                    
                                self.lastLeftPoint = event.pos()
                                for shape in self.shapes:  # iterate through shapes
                                    if shape.position.x() - 15 <= self.lastLeftPoint.x() <= shape.position.x() + 15 and shape.position.y() - 15 <= self.lastLeftPoint.y() <= shape.position.y() + 15:
                    
                                        if shape.target.toBool():  # if is target
                                            print("clicked the target!")
                                            self.click = True  # set click to true
                                        else:
                                            print("not this one")
                                        self.update()
                    
                        def keyPressEvent(self, e):
                            rules = self.rules["responserules"].toArray()  # get response rules of the board
                            if self.click:
                                if "any" == rules[0].toString() and type(e.key()) is int:  # if rule is any and pressed any key
                                    self.finish = True
                                    print("updated") # verified that this is hit by printing statement
                                else:
                                    myList = [Qt.Key_Q, Qt.Key_W, Qt.Key_E, Qt.Key_R, Qt.Key_T]
                                    if e.text() in myList:
                                        print("In My List")  # if clicked a key in the set
                    
                    
                    jsulmJ 1 Reply Last reply
                    0
                    • H htjane

                      Hi all,
                      Sorry I'm new to Qt. Here again asking a follow-up question about reading board instance attributes that have just been modified by keypress event. Not sure if I should post it here or open a new thread. Please Lmk.

                      My question is in the KeyPressEvent of Board class, I set the self.finish attribute to True to indicate the target shape has been clicked and a key pressed, then in MyApp class I want to get the finish attribute of board instance using an if-condition to check if the board has been finished. But the code in MyApp executes before "finish" has been modified by KeyPressEvent, without hanging or waiting for it and "finish" is False whenever I print it in MyApp class. Specifically, I want to read "finish" of each board in MyApp and if it's True, set the entry_time of the next board to 0.5s to prevent waiting this board's duration to expire. Could you guys suggest some solutions?

                      class MyApp(QMainWindow):
                      # constructor and some functions...
                        def showTrial1(self, qjson):
                              self.ui.stackedWidget.setCurrentWidget(self.ui.trial1)
                      
                              rulesets = qjson["rulesets"].toObject()
                              boardArr = qjson["boards"].toArray()
                      
                              for b in boardArr:  # create boards
                                  board = b.toObject()
                                  bd = Board(rulesets, board, self.geometry())
                                  self.boards.append(bd)
                                  self.ui.stackedWidget.addWidget(bd)
                      
                              for bd in self.boards:
                                  #call a static timer to draw board based on entry_time
                                  QTimer.singleShot(int(bd.entry_time) * 1000, lambda arg=bd: self.createBoard(arg))
                      
                          def createBoard(self, board):
                              board.drawShapes()
                              self.ui.stackedWidget.setCurrentWidget(board)
                      
                      class Board(QWidget):
                          def __init__(self, rulesets, board, size, parent=None):
                              super().__init__(parent)
                              self.rules = rulesets
                              self.lastLeftPoint = QPoint(0, 0)
                              self.id = board["id"].toInt()
                              self.duration = 10  # board["duration"]
                              self.entry_time = board["entry_time"].toDouble()
                              self.stimuli = board["stimuli"]
                              self.shapes = []
                              self.click = False
                              self.boardSize = size
                              self.timeout = False
                              self.finish = False
                      
                          def drawShapes(self):
                              stiArr = self.stimuli.toArray()
                      
                              for s in stiArr:
                      
                                  stimuli = s.toObject()
                      
                                  ID = stimuli["id"].toInt()
                                  # print(ID)
                                  color = QtGui.QColor(stimuli["color"].toObject()["color"].toString())
                                  text = stimuli["text"].toString()
                                  x = math.floor(
                                      stimuli[
                                          "column"].toInt() * self.boardSize.width() / 12.0 - self.boardSize.width() / 24.0)  # 3862 * 2122
                                  y = math.floor(stimuli["row"].toInt() * self.boardSize.height() / 12.0 - self.boardSize.height() / 24.0)
                                  pos = QtCore.QPoint(x, y)
                                  target = stimuli["target"]
                                  response = stimuli["response"]
                                  # hue = clr["hue"].toInt()
                                  # saturation = clr["saturation"].toInt() * 255
                                  # value = clr["value"].toInt() * 255
                                  # alpha = clr["alpha"].toInt() * 255
                                  if stimuli["shape"] == "circle":
                                      self.shapes.append(Circle(ID, 30, pos, color, text, target, response))
                                  elif stimuli["shape"] == "cross":
                                      self.shapes.append(Cross(ID, 30, pos, color, text, target, response))
                                  elif stimuli["shape"] == "star":
                                      self.shapes.append(Star(ID, 30, pos, color, text, target, response))
                                  elif stimuli["shape"] == "hexagon":
                                      self.shapes.append(Hexagon(ID, 30, pos, color, text, target, response))
                                  elif stimuli["shape"] == "octagon":
                                      self.shapes.append(Octagon(ID, 30, pos, color, text, target, response))
                                  elif stimuli["shape"] == "pentagon":
                                      self.shapes.append(Pentagon(ID, 30, pos, color, text, target, response))
                              # self.update()
                      
                          def paintEvent(self, event):
                              painter = QPainter(self)
                              painter.setRenderHint(QPainter.Antialiasing)
                              if self.timeout:
                                  print("cleared!  " + getTimestamp())
                                  painter.eraseRect(0, 0, self.boardSize.width(), self.boardSize.height())
                                  return
                              for shape in self.shapes:
                                  shape.paint(painter)
                              if self.click:
                                  painter.setPen(QPen(QColor("green"), 4, Qt.SolidLine))
                                  painter.drawRect(self.lastLeftPoint.x() - 15, self.lastLeftPoint.y() - 15, 30, 30)
                                  painter.end()
                      
                          def mousePressEvent(self, event):
                              # on left mouse click, it returns the coordinates
                              if event.button() == Qt.LeftButton:
                      
                                  self.lastLeftPoint = event.pos()
                                  for shape in self.shapes:  # iterate through shapes
                                      if shape.position.x() - 15 <= self.lastLeftPoint.x() <= shape.position.x() + 15 and shape.position.y() - 15 <= self.lastLeftPoint.y() <= shape.position.y() + 15:
                      
                                          if shape.target.toBool():  # if is target
                                              print("clicked the target!")
                                              self.click = True  # set click to true
                                          else:
                                              print("not this one")
                                          self.update()
                      
                          def keyPressEvent(self, e):
                              rules = self.rules["responserules"].toArray()  # get response rules of the board
                              if self.click:
                                  if "any" == rules[0].toString() and type(e.key()) is int:  # if rule is any and pressed any key
                                      self.finish = True
                                      print("updated") # verified that this is hit by printing statement
                                  else:
                                      myList = [Qt.Key_Q, Qt.Key_W, Qt.Key_E, Qt.Key_R, Qt.Key_T]
                                      if e.text() in myList:
                                          print("In My List")  # if clicked a key in the set
                      
                      
                      jsulmJ Online
                      jsulmJ Online
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #12

                      @htjane Why don't you simply emit a "finished" signal to notify others that it is finished? This is how Qt applications (or any other event driven applications) work.

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      H 1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        @htjane Why don't you simply emit a "finished" signal to notify others that it is finished? This is how Qt applications (or any other event driven applications) work.

                        H Offline
                        H Offline
                        htjane
                        wrote on last edited by htjane
                        #13

                        @jsulm Thanks! I used signal and slot and now they work well!

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved