code: def run(self):
      col_idx = 0
      # since the chunks don't preserve row number, need to keep track of
      # chunks processed to get row number
      chunks_in_column = 0
      for chunk in self.chunks:
          try:
              # gives series with dtype bool
              rows_with_match = self.get_matches(chunk)
              # gives indicies where the series is True
              row_idx_with_match = [
                  chunk.index.get_loc(i)
                  + chunks_in_column * self.max_chunk_size
                  for i in rows_with_match.index
              ]
              # output list of table coordinates where match is found
              coords_with_match = [
                  (row_idx, col_idx) for row_idx in row_idx_with_match
              ]
  
              # check if a stop is requested
              # (in case the user types another letter)
              if self.isRunning:
                  self.matches.emit(coords_with_match)
              else:
                  break
  
              chunks_in_column += 1
  
              # if the last index of the chunk is equal to the last index
              # of the whole dataframe, move to the next column
              if chunk.index[-1] == self.df.index[-1]:
                  col_idx += 1
                  chunks_in_column = 0
  
              # waits 50 milliseconds to process gui interactions,
              # so the gui does not freeze
              time.sleep(0.05)
          except re.error:
              break
      self.isRunning = False
  
imports: import re
  import time
  import pkg_resources
  from PyQt5 import QtCore, QtGui, QtWidgets
  from PyQt5.QtCore import Qt
label_desc: Use image node_id 4 for calling the FindThread obj's underlying member method code with example usage: obj.run() without return types