-1

I am trying to update a counter variable inside my GUI that is constantly changing. From my source code, at line 50, "NothingFound_Counter" and "Total" are global variables from another function dynamically changing. I want the GUI to also reflect this but the way I have it so far is only displaying the initialized static value at 0.

I have two dilemmas I am trying to solve here

  1. Update the global variables so that the GUI will also refresh the value when the value of this variable changes

  2. I want to take the inputs of the buttons from this GUI function as the inputs to my other function. What is the proper syntax to do this?

import sys
import os
import fut
import PyQt5
import random
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class GuiWindow(QWidget):
   def __init__(self, parent = None):
      super(GuiWindow, self).__init__(parent)

      global Found_Counter
      global NothingFound_Counter

      #self.setFixedWidth(300)
      #self.setFixedHeight(150)
      self.resize(300,150)
        
      layout = QFormLayout()
      self.btn = QPushButton("Style")
      self.btn.clicked.connect(self.getItem)

      self.le = QLineEdit()
      layout.addRow(self.btn,self.le)
      self.btn1 = QPushButton("Name")
      self.btn1.clicked.connect(self.gettext)
        
      self.le1 = QLineEdit()
      layout.addRow(self.btn1,self.le1)
      self.btn2 = QPushButton("Max Buy Now")
      self.btn2.clicked.connect(self.getint)
        
      self.le2 = QLineEdit()
      layout.addRow(self.btn2,self.le2)
      self.setLayout(layout)
      self.setWindowTitle("clicker :D")

      self.run = QPushButton('RUN', self)
      self.run.clicked.connect(self.clickMethod)
      self.run.resize(100,32)
      self.run.move(150,100)

      self.counter1 = QtWidgets.QLabel('',self)
      layout = QtWidgets.QHBoxLayout(self)
      layout.addWidget(self.counter1, alignment=QtCore.Qt.AlignBottom)
      self.counter1.move(50,100)
      self.counter1.setText(f'Items Found is {fut.NothingFound_Counter} / {fut.Total}')
        
   def getItem(self):
      items = ("test1", "test2", "test3" )
        
      item, ok = QInputDialog.getItem(self, "select input dialog", 
         "list of styles", items, 0, False)
            
      if ok and item:
         self.le.setText(item)
            
   def gettext(self):
      text, ok = QInputDialog.getText(self, 'Text Input Dialog', 'Enter the name:')
        
      if ok:
         self.le1.setText(str(text))
            
   def getint(self):
      num,ok = QInputDialog.getInt(self,"integer input dualog","enter a number")
        
      if ok:
         self.le2.setText(str(num))
             
   def clickMethod(self):
        fut.Main()



        
            
def main(): 
   app = QApplication(sys.argv)
   ex = GuiWindow()
   ex.show()
   sys.exit(app.exec_())
    
if __name__ == '__main__':
   main()

simplified fut function is as such:

import os
import csv
import pip._vendor.requests
import pyautogui
import time
import PIL
from PIL import Image
import urllib.request
import re
import random
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import gui

Found_Counter = 0
NothingFound_Counter = 0
Total = 0


def NoResultsFound():
    global Found_Counter
    global NothingFound_Counter
    NoResultsLocation = pyautogui.locateOnScreen('NoResultsFound2.png', region = (1205, 846, 500, 160))
    time.sleep(2)
    if NoResultsLocation == None:
        Found_Counter = Found_Counter + 1
    else:
        NothingFound_Counter = NothingFound_Counter + 1 
    Total = Found_Counter + NothingFound_Counter    
    print(f'NothingFound_Count = {NothingFound_Counter}')
    print(f'Found_Count = {Found_Counter}')
    print(f'Total = {Total}')


def Main():
    while True:
        time.sleep(random.randrange(1,5))
        #goTransfer()
        for x in range (10):
            NoResultsFound()
        time.sleep(random.randrange(1,5))
        clearTransfer()
        time.sleep(random.randrange(1,5))
ruawzrd
  • 1
  • 4
  • please provide a [mre], what is `fut`? Also avoid global variables: https://stackoverflow.com/questions/19158339/why-are-global-variables-evil – eyllanesc Oct 01 '21 at 05:23
  • 1
    No, I don't want to imagine. Here we need precise data so please edit your post and add what is necessary for your code to be an MRE. Please read [ask] and review the [tour]. Not external links – eyllanesc Oct 01 '21 at 05:35
  • I edited my post as it pleases you. In theory, The FUT function is irrelevant as the point is I have a dynamic variable coming in and I would like to know the proper syntax to update it in the GUI function. – ruawzrd Oct 01 '21 at 05:45
  • No, on the contrary it is relevant since the problem is the implementation of fut. – eyllanesc Oct 01 '21 at 05:46
  • okay understood, I'll keep your suggestions in mind for all future posts. Thank you – ruawzrd Oct 01 '21 at 05:51
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Oct 08 '21 at 07:37

1 Answers1

0

Should consider:

  • Global variables are not necessary, it is not used to send information between modules.

  • If there is a time consuming task then you should run it in another thread so as not to crash the GUI. In addition, signals must be used to send information between threads.

  • The idea of the modules is to encapsulate the logic through classes and functions and that they can be reused

from dataclasses import dataclass
import random
import threading
import time

import pyautogui

from PyQt5.QtCore import pyqtSignal, QObject


@dataclass
class Worker(QObject):
    found_counter: int = 0
    not_found_counter: int = 0

    changed = pyqtSignal(int, int, int)

    @property
    def total(self):
        return self.found_counter + self.not_found_counter

    def __post_init__(self):
        super().__init__()

    def start(self):
        threading.Thread(target=self._execute, daemon=True).start()

    def _process(self):
        r = pyautogui.locateOnScreen(
            "NoResultsFound2.png", region=(1205, 846, 500, 160)
        )
        if r is None:
            self.found_counter += 1
        else:
            self.not_found_counter += 1
        print(f"NothingFound_Count = {self.not_found_counter}")
        print(f"Found_Count = {self.found_counter}")
        print(f"Total = {self.total}")
        self.changed.emit(self.found_counter, self.not_found_counter, self.total)

    def _execute(self):
        while True:
            time.sleep(random.randrange(1, 5))
            for x in range(10):
                self._process()
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
    QApplication,
    QFormLayout,
    QHBoxLayout,
    QInputDialog,
    QLabel,
    QLineEdit,
    QPushButton,
    QWidget,
)

from fut import Worker


class GuiWindow(QWidget):
    def __init__(self, parent=None):
        super(GuiWindow, self).__init__(parent)
        self.resize(300, 150)

        layout = QFormLayout(self)
        self.btn = QPushButton("Style")
        self.btn.clicked.connect(self.getItem)

        self.le = QLineEdit()
        layout.addRow(self.btn, self.le)
        self.btn1 = QPushButton("Name")
        self.btn1.clicked.connect(self.gettext)

        self.le1 = QLineEdit()
        layout.addRow(self.btn1, self.le1)
        self.btn2 = QPushButton("Max Buy Now")
        self.btn2.clicked.connect(self.getint)

        self.le2 = QLineEdit()
        layout.addRow(self.btn2, self.le2)
        self.setWindowTitle("clicker :D")

        self.run = QPushButton("RUN", self)
        layout.addRow(self.run)
        self.run.clicked.connect(self.clickMethod)

        self.counter1 = QLabel("", self)
        layout.addRow(self.counter1)

        self.worker = Worker()
        self.worker.changed.connect(self.handle_changed)

    def getItem(self):
        items = ("test1", "test2", "test3")

        item, ok = QInputDialog.getItem(
            self, "select input dialog", "list of styles", items, 0, False
        )

        if ok and item:
            self.le.setText(item)

    def gettext(self):
        text, ok = QInputDialog.getText(self, "Text Input Dialog", "Enter the name:")

        if ok:
            self.le1.setText(str(text))

    def getint(self):
        num, ok = QInputDialog.getInt(self, "integer input dualog", "enter a number")

        if ok:
            self.le2.setText(str(num))

    def handle_changed(self, found_counter, not_found_counter, total):
        self.counter1.setText(f"Items Found is {found_counter} / {total}")

    def clickMethod(self):
        self.worker.start()


def main():
    app = QApplication(sys.argv)
    ex = GuiWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
eyllanesc
  • 221,139
  • 17
  • 121
  • 189
  • Thank you so much. I need to understand a few lines that you added but for sake of your time I will try to research myself first.. My next question is in regards to importing the "getint" "gettext" and "getItem" from GUI function back into the FUT function. When I try to import GUI function back into FUT, I get circular import. What is the best practice to remedy this? -- To clarify, I want to use the values from the user GUI input as input variables to certain functions inside of FUT – ruawzrd Oct 01 '21 at 06:48