I'm trying to run a GUI on a separate process from my "main" program while still being able to retrieve values from the GUI in the "main" module.
Right now I have a simple GUI setup with a simple function on the "main" module to get several values triggered by a button press.
I have instantiated both classes in my "main" module but after I start the GUI process, press the 'start' button to trigger my retrieve & print function I receive the following error:
NameError: name 'start' is not defined
"main" module:
#############################
#### Importing Libraries ####
#############################
from GUI import *
#############################
#### Creating Main Class ####
#############################
class Round_Sling_Main:
def sling_start(self):
current_length = start.get_length()
current_speed = start.get_speed()
current_color = start.get_color()
print(current_length, current_speed, current_color)
if __name__ == "__main__":
round_sling = Round_Sling_Main()
start = GUI(round_sling, 0, 0, "").start()
GUI module:
#############################
#### Importing Libraries ####
#############################
import tkinter as tk
from tkinter import ttk
import sys
from multiprocessing import Process
############################
#### Creating Front GUI ####
############################
class GUI(Process):
def __init__(self, round_sling, length, speed, color):
super(GUI, self).__init__()
self.round_sling = round_sling
self.length = length
self.speed = speed
self.color = color
self.create_GUI()
def retrieve_length(self, length):
self.length = length
def retrieve_speed(self, speed):
self.speed = speed
def retrieve_color(self, event = None):
self.color = event.widget.get()
def get_length(self):
return self.length
def get_speed(self):
return self.speed
def get_color(self):
return self.color
def close(self):
sys.exit()
def create_GUI(self):
while(1):
front = tk.Tk()
front.title ("Round Sling Machine")
front.geometry ('800x600')
#front.config (cursor = 'none')
#front.attributes ("-fullscreen", True)
# Color Selection Label
Color_Label = tk.Label (front, text = 'Select a Sling Color', font = 'Verdana 12')
Color_Label.place(x = 300, y = 0)
# Material Selection Label
Material_Label = tk.Label (front, text = 'Select a Sling Material', font = 'Verdana 12')
Material_Label.place(x = 300, y = 80)
# Length Entry Label
Length_Label = tk.Label (front, text = 'Select Desired Sling Length (inches)', font = 'Verdana 12')
Length_Label.place(x = 240,y = 160)
# Speed Factor Label
Speed_Label = tk.Label (front, text = 'Enter Motor Speed Factor (0.0 - 1.0)', font = 'Verdana 8')
Speed_Label.place(x = 25, y = 35)
# Color Selection Combo Box
ColorVar = tk.StringVar()
SlingColor = ttk.Combobox(front, width = 27, textvariable = ColorVar)
SlingColor['values'] = ('Purple',
'Green',
'Yellow',
'Tan',
'Red',
'White',
'Blue',
'Orange 1',
'Orange 2',
'Orange 3',
'Orange 4',
'Orange 5',
'Orange 6')
SlingColor.state(["readonly"])
SlingColor.place(x = 300, y = 30)
SlingColor.bind("<<ComboboxSelected>>", self.retrieve_color)
# Material Selection Combo Box
MaterialVar = tk.StringVar()
MaterialSel = ttk.Combobox(front, width = 27, textvariable = MaterialVar)
MaterialSel['values'] = ('Nylon', 'Polyester', 'Carbon Fiber')
MaterialSel.state(["readonly"])
MaterialSel.place(x = 300, y = 110)
# Sling Length Slider
SlingLength = tk.Scale(front, from_ = 0, to = 100, length = 600, orient=tk.HORIZONTAL, command = self.retrieve_length)
SlingLength.place(x = 105, y = 190)
# Motor Speed Factor Slider
MotorSpeed = tk.Scale(front, from_ = 0, to = 1.0, resolution = 0.1, length = 200, orient=tk.HORIZONTAL, command = self.retrieve_speed)
MotorSpeed.place(x = 25, y = 50)
startBtn = tk.Button(front, text = 'Start', font = 'Verdana 12', command = self.round_sling.sling_start)
startBtn.place(x = 250, y = 250)
closeBtn = tk.Button(front, text = 'Close', font = 'Verdana 12', command = self.close)
closeBtn.place(x = 450, y = 250)
front.mainloop()
############################
##### End of Front GUI #####
############################
Related
UI is Freezing even after running the background process in separate Thread.
Db2Input = c1.fetchone() is taking few seconds to fetch the data from table as you can see it in the screenshot and I have recursive call to fetchData.
I thought Separate Thread won't have any interference with main Thread since I am not using any GUI element in FetchData() Function. Any suggestions...
from tkinter import *
import pyodbc
import connect
from datetime import datetime
import threading as th
class appLayout(Tk):
def __init__(self):
Tk.__init__(self)
self.masterPane = PanedWindow(self,bd=0,sashwidth =0 )
self.leftPane = Frame(self.masterPane,bg = 'orange',height = 400,width = 200,relief = 'raised')
self.masterPane.add(self.leftPane)
self.rightPane = Frame(self.masterPane,bg = 'blue',height =400,width =500)
self.masterPane.add(self.rightPane)
self.masterPane.pack(fill = 'both',expand = True)
self.AddButton()
def on_enter(self,e):
e.widget['background'] = 'green'
def on_leave(self,e):
e.widget['background'] = 'orange'
def AddButton(self):
btn1 = Button(self.leftPane, text = 'Dashboard ', bg ='orange',relief ='flat',
bd =0,padx =10,pady=7,font ='Arial',fg='white',activebackground = 'green',command =self.SubmitThread)
btn2 = Button(self.leftPane, text = 'Dashboard ', bg ='orange',relief ='flat',
bd =0,padx =10,pady=7,font ='Arial',fg='white')
btn3 = Button(self.leftPane, text = 'Dashboard ', bg ='orange',relief ='flat',
bd =0,padx =10,pady=7,font ='Arial',fg='white')
btn1.grid(row =2,column =0,sticky ='nwe',ipady=5)
btn2.grid(row =3,column =0,sticky ='nwe',ipady=5)
btn3.grid(row =4,column =0,sticky ='nwe',ipady=5)
btn1.bind("<Enter>", self.on_enter)
btn1.bind("<Leave>", self.on_leave)
btn2.bind("<Enter>", self.on_enter)
btn2.bind("<Leave>", self.on_leave)
btn3.bind("<Enter>", self.on_enter)
btn3.bind("<Leave>", self.on_leave)
def SubmitThread(self):
th.Thread(target = self.fetchData).start()
def fetchData(self):
connection = connect.connect('ADMIN','USER','Password')
AS400Connection = connection.ToAS400Database()
c1 = AS400Connection.cursor()
sqlstatement = ("SELECT * FROM (SELECT * FROM TABLE(QSYS2.JOB_INFO(JOB_STATUS_FILTER => '*OUTQ',\
JOB_USER_FILTER =>'{}') )) WHERE JOB_TYPE ='BCH' AND JOB_NAME LIKE '%{}%'\
AND JOB_E00002 > '{}' ORDER BY JOB_E00002".format('USER','TEST','2021-06-11-10.25.00'))
print("Before Execution",datetime.now())
c1.execute(sqlstatement)
print("Before fetch",datetime.now())
**Db2Input = c1.fetchone()**
print("After fetch",datetime.now())
c1.close()
self.after(3000,self.fetchData)
app = appLayout()
app.mainloop()
enter image description here
I have a HangMan game created using a class. I want to delete all the child widgets with a single deletion of the parent window.
My game shows a difficulty window, which is being destroyed after the user selects a difficulty and the main game window appears; which is destroyed too after the user completes the game and then a replay window appears; which is destroyed too after the user clicks yes and a new instance of the difficulty pop-up appears again and the whole thing happens intetely until the user says no.
My code looks like this:
class HangMan:
font = ('Comic Sans MS', 20, 'bold')
theme = 'Dark'
allWords = []
stages = None
title = None
def __init__(self):
self.tries = None
self.pWord = None
self.word = None
self.used = []
self.char = None
def setup(self, path, stges, title="HangMan"):
with open(path, 'r') as file:
self.allWords = file.read().split()
del file
self.stages = stges
self.title = title
def play(self):
def setTheme(theme, place):
if theme == 'Dark':
b = 'black'
f = 'white'
else:
b = 'white'
f = 'black'
if place == 'askDiff':
self.diffWindow.config(bg = b)
self.diffFrame['bg'] = b
i = [self.diffLabel, self.db1, self.db2, self.db3]
elif place == 'Main':
self.window.config(bg = b)
inputEntry['insertbackground'] = f
for i in [frame1, frame2]:
i['bg'] = b
i = [wordLabel, themeButton, ph, inputEntry, triesLabel, usageLabel, logLabel]
elif place == 'askReplay':
self.replayWindow.config(bg = b)
self.reFrame['bg'] = b
i = [self.reLabel, self.reb1, self.reb2]
for j in i:
j['bg'] = b
j['fg'] = f
def changeTheme():
if self.theme == 'Dark':
self.theme = 'Light'
else:
self.theme = 'Dark'
themeButton['text'] = self.theme
setTheme(self.theme, 'Main')
def replay():
self.replayWindow.destroy()
self.__init__()
self.play()
def askReplay(event):
#Destroying the running game
self.window.destroy()
#Creating the replay Window
self.replayWindow = Tk()
self.replayWindow.title('Re-Experience?')
self.reLabel = Label(master = self.replayWindow, font = self.font, text = "Wanna replay?\nSwear it'll be a different word...")
self.reLabel.pack()
self.reFrame = Frame(master = self.replayWindow)
self.reFrame.pack()
self.reb1 = Button(master = self.reFrame, font = self.font, text = 'Yup', command = replay)
self.reb1.pack(side = 'left')
self.reb2 = Button(master = self.reFrame, font = self.font, text = 'Later.', command = lambda: self.replayWindow.destroy())
self.reb2.pack(side = 'left')
setTheme(self.theme, 'askReplay')
self.replayWindow.mainloop()
def askDiff():
def returnStage(num):
nonlocal x
x = num
self.diffWindow.destroy()
self.diffWindow = Tk()
self.diffWindow.title('Difficulty')
self.diffLabel = Label(master = self.diffWindow, font = self.font, text = 'Choose your level of difficulty: ')
self.diffLabel.pack()
self.diffFrame = Frame(master = self.diffWindow)
self.diffFrame.pack()
x=None
self.db1 = Button(master = self.diffFrame, font = self.font, text = self.stages[0]['stage'], command = lambda: returnStage(0))
self.db1.pack(side = 'left')
self.db2 = Button(master = self.diffFrame, font = self.font, text = self.stages[1]['stage'], command = lambda: returnStage(1))
self.db2.pack(side = 'left')
self.db3 = Button(master = self.diffFrame, font = self.font, text = self.stages[2]['stage'], command = lambda: returnStage(2))
self.db3.pack(side = 'left')
setTheme(self.theme, 'askDiff')
self.diffWindow.mainloop()
return x
def setDiff(i):
from random import choice
wordLenRange = (self.stages[i]['wordLen']['min'], self.stages[i]['wordLen']['max'])
possibleWords = []
for j in self.allWords:
if len(j) in range(wordLenRange[0], wordLenRange[1] + 1):
possibleWords.append(j)
self.word = list(choice(possibleWords).lower())
self.pWord = ''.join(self.word)
self.allWords.remove(self.pWord)
self.tries = self.stages[i]['tries']
def isValid(string):
if len(string)==1 and string.isalpha():
return True
else:
return False
def isUsed(string):
if string in self.used or string in wordLabel['text']:
return True
else:
return False
def isRight(string):
if string in self.word:
return True
else:
return False
def updateLog(x):
if x == 'invalid input':
logLabel['text'] = 'Enter a valid single alphabet'
elif x == 'in word':
logLabel['text'] = 'This letter is revealed'
elif x == 'in used':
logLabel['text'] = 'You have already used this letter'
elif x == 'right':
logLabel['text'] = 'Good Guess...'
elif x == 'wrong':
logLabel['text'] = 'You missed it.'
elif x == 'win':
logLabel['text'] += '\nYou Win...Press any key...'
else:
logLabel['text'] += '\nYou Lost...The word is revealed.\nPress any key...'
def updateWord():
txt = list(wordLabel['text'])
while self.char in self.word:
index = self.word.index(self.char)
txt[index] = self.char
self.word[index] = '*'
txt = ''.join(txt)
wordLabel['text'] = txt
def updateTries():
self.tries -= 1
triesLabel['text'] = '{} Oops left'.format(self.tries)
def updateUsage():
self.used.append(self.char)
usageLabel['text'] = 'Used Letters: {}'.format(', '.join(self.used))
def processGame(event):
self.char = inputEntry.get().strip()
if isValid(self.char):
self.char = self.char.lower()
if isUsed(self.char):
if self.char in wordLabel['text']:
updateLog('in word')
else:
updateLog('in used')
else:
if isRight(self.char):
updateWord()
updateLog('right')
else:
updateTries()
updateUsage()
updateLog('wrong')
else:
updateLog('invalid input')
inputEntry.delete(0, 'end')
if '*' not in wordLabel['text']:
updateLog('win')
inputEntry.bind('<Key>', askReplay)
if self.tries == 0:
updateLog('lost')
wordLabel['text'] = self.pWord
inputEntry.bind('<Key>', askReplay)
## GUI Design
from tkinter import Tk, Label, Entry, Button, Frame
#Diffficulty PopUp
diff = askDiff()
setDiff(diff)
# Main Window
self.window = Tk()
self.window.title(self.title)
# Frames and Buttons
frame1 = Frame(master = self.window)
frame1.pack(fill = 'x')
wordLabel = Label(master = frame1, font = self.font, text = '*'*len(self.word))
wordLabel.pack()
themeButton = Button(master = frame1, font = ("Comic Sans MS", 12), text = self.theme, command = changeTheme)
themeButton.pack(side = 'right')
frame2 = Frame(master = self.window)
frame2.pack()
ph = Label(master = frame2, font = self.font, text = 'Guess a Letter: ')
ph.pack(side = 'left')
inputEntry = Entry(master = frame2, font = self.font, width = 5)
inputEntry.focus_set()
inputEntry.pack(side = 'left')
triesLabel = Label(master = frame2, font = self.font, text = '{} Oops left'.format(self.tries))
triesLabel.pack(side = 'left')
usageLabel = Label(master = self.window, font = self.font, text = 'Used Letters: -')
usageLabel.pack()
logLabel = Label(master = self.window, font = self.font, text = "-:Log:-")
logLabel.pack()
setTheme(self.theme, 'Main')
#Event Handler and MainLoop
self.window.bind('<Return>', processGame)
self.window.mainloop()
path = "words.txt"
stages = ({'stage': 'Cool', 'tries':10, 'wordLen':{'min':3, 'max':5}}, {'stage': 'Engaging', 'tries':6, 'wordLen':{'min':6, 'max':8}}, {'stage': 'Intense', 'tries': 4, 'wordLen': {'min': 9, 'max': 15}})
game1 = HangMan()
game1.setup(path, stages)
game1.play()
At 3 places, I'm destroying the parent window - in the askReplay() fucntion of the class.play() function, in the returnStage() function of the askDiff() function in the class.play() function & in the replay() function of the class.play() function. I tried self.window.destroy(), but it is only destroying the root window and all its child widgets are still occupying the memory (I know this because I tried to print one of the child widgets after the window was destroyed). How can I do this?
This would be a problem if an obsessive player plays my game for a
thousand times, creating more than 7000 trash widgets in the memory.
One implementation would be to have the top-level object track its widgets via a list, then have a .close() method that looks something like:
def close(self):
for widget in self.widgets:
widget.destroy()
self.destroy()
I have seen some information posted about this, but everything seems to be with PyQt4 not PyQt5 and I'm not sure if there is a difference. I couldn't get anything to work.
What I want to do is have the program update a QLabel after the user inputs text into it and saves it. Right now I have the main window, with either a button or a selection from a drop down menu that will pop up a window with the ability to change setpoints.
Now what happens is the user can put in new data, but the code seems to still run and not wait for the user to make a change in the popup. calling my updateSetpoints function before anything changes.
# popups the reactorSetpoints window to change the setpoints for
# the reactor. This is where I am haiving troubles, the code
# continues before the user can input new setpoints
def reactorSetpoints(self):
exPopup = setpointsPopup(self)
self.updateSetpoints()
# just have it update the one value for now
def updateSetpoints(self):
self.pHUpperValue.setText(str(upper_pH))
A button calls reactorSetpoints(self) and popups a new window
import sys
import matplotlib.pyplot as plt
import random
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication,QLineEdit, QPushButton, QWidget, QDialog, QTextEdit, QLabel, QMenu, QVBoxLayout, QSizePolicy
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt, QTime, QTimer, QRect
from PyQt5 import QtCore
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
debug = True
setPointsChanged = False
versionNumber = 'V0.0.1'
currentState = 'Treatment'
currentCycTime = '2:15:42'
remaningCycTime = '5:44:18'
current_pH = 6.85
current_DO = 1.90
currentTemp = 24.9
lower_pH = 6.95
upper_pH = 7.20
lower_DO = 2.00
def openFile():
if debug == True:
print("Open File")
def saveFile():
if debug == True:
print("Save File")
def saveFileAs():
if debug == True:
print("Save File As...")
def editSysParm():
if debug == True:
print("Edit system parameters")
def reactorParameters():
if debug == True:
print("Edit reactor parameters")
def pHCalibration():
if debug == True:
print("pH Calibration")
def dOCalibration():
if debug == True:
print("DO calibration")
def pumpCalibration():
if debug == True:
print("Pump calibrations")
def editpHSetpoints():
pass
# sets up the setpoints popup window with either the option to save
# new setpoints, or to quit
class setpointsPopup(QDialog):
def __init__(self, parent = None):
super().__init__(parent)
self.initUI()
def initUI(self):
self.setGeometry(100,100,300,300)
self.upH = QLabel('Upper pH: ',self)
self.lpH = QLabel('Lower pH: ',self)
self.lDO = QLabel('Lower DO: ',self)
self.upHE = QLineEdit(self)
self.lpHE = QLineEdit(self)
self.lDOE = QLineEdit(self)
self.upHE.setPlaceholderText(str(upper_pH))
self.lpHE.setPlaceholderText(str(lower_pH))
self.lDOE.setPlaceholderText(str(lower_DO))
self.exitSetpoints = QPushButton('Exit', self)
self.saveSetpoints = QPushButton('Save New Setpoints', self)
self.upH.move(5,5)
self.upHE.move(90,5)
self.lpH.move(5,40)
self.lpHE.move(90,40)
self.lDO.move(5,75)
self.lDOE.move(90,75)
self.exitSetpoints.setGeometry(QRect(5,120,50,30))
self.exitSetpoints.clicked.connect(self.destroy)
self.saveSetpoints.setGeometry(QRect(60,120,150,30))
self.saveSetpoints.clicked.connect(self.verifySetpoints)
self.show()
#verification will be put here to make sure the input is valid
#but for now it will accept anything for ease of testing
def verifySetpoints(self):
global upper_pH
newUpH = self.upHE.text()
upper_pH = float(newUpH)
print(newUpH)
# Main window
class drawMenuBar(QMainWindow):
def __init__(self):
super().__init__()
self.topL = 20
self.top = 40
self.width = 1000
self.height = 500
self.title = ('Batch Reactor Controller ' + versionNumber)
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.topL, self.top, self.width, self.height)
exitAct = QAction('&Exit' , self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit Application')
exitAct.triggered.connect(qApp.quit)
openAct = QAction('&Open', self)
openAct.setShortcut('Ctrl+O')
openAct.setStatusTip('Open File')
openAct.triggered.connect(openFile)
saveAsAct = QAction('&Save As..', self)
saveAsAct.setShortcut('Shift+Ctrl+S')
saveAsAct.setStatusTip('Save as new file')
saveAsAct.triggered.connect(saveFileAs)
saveAct = QAction('Save', self)
saveAct.setStatusTip('Save')
saveAct.setShortcut('Ctrl+S')
saveAct.triggered.connect(saveFile)
systemSetpointsAct = QAction('Preferences', self)
systemSetpointsAct.setStatusTip('Edit system parameters')
systemSetpointsAct.triggered.connect(editSysParm)
reactorSetpointsAct = QAction('Reactor Setpoints', self)
reactorSetpointsAct.setStatusTip('Edit reactor setpoints')
reactorSetpointsAct.triggered.connect(self.reactorSetpoints)
reactorParametersAct = QAction('Reactor Parameters', self)
reactorParametersAct.setStatusTip('Edit batch reactor profiles')
reactorParametersAct.triggered.connect(reactorParameters)
pHCalibrationAct = QAction('pH Calibration', self)
pHCalibrationAct.setStatusTip('pH Calibration')
pHCalibrationAct.triggered.connect(pHCalibration)
dOCalibrationAct = QAction('DO Calibration', self)
dOCalibrationAct.setStatusTip('Dissolved oxygen calibration')
dOCalibrationAct.triggered.connect(dOCalibration)
pumpCalibrationAct = QAction('Pump Calibrations', self)
pumpCalibrationAct.setStatusTip('Pump Calibrations')
pumpCalibrationAct.triggered.connect(pumpCalibration)
menubar = self.menuBar()
self.statusBar()
fileMenu = menubar.addMenu('&File')
editMenu = menubar.addMenu('&Edit')
calibrationMenu = menubar.addMenu('&Calibration')
fileMenu.addAction(openAct)
fileMenu.addAction(saveAct)
fileMenu.addAction(saveAsAct)
fileMenu.addAction(exitAct)
calibrationMenu.addAction(pHCalibrationAct)
calibrationMenu.addAction(dOCalibrationAct)
calibrationMenu.addAction(pumpCalibrationAct)
editMenu.addAction(systemSetpointsAct)
editMenu.addAction(reactorSetpointsAct)
self.reactorTitle = QLabel('<b><u>Reactor 1 Status</u></b>', self)
font = self.reactorTitle.font()
font.setPointSize(20)
self.reactorTitle.setFont(font)
self.reactorTitle.setGeometry(QtCore.QRect(10,30, 250, 45)) #(x, y, width, height)
#pH Label
self.pHLabel = QLabel('<span style="color:blue"><b>pH:</b></span>',self)
font = self.pHLabel.font()
font.setPointSize(22)
self.pHLabel.setFont(font)
self.pHLabel.setGeometry(QtCore.QRect(10,50,100,100))
#displays current pH value
self.currentpH = QLabel('<b>' + str(current_pH) + '</b>', self)
font = self.currentpH.font()
font.setPointSize(22)
self.currentpH.setFont(font)
self.currentpH.setGeometry(QtCore.QRect(60,50,100,100))
#display lowerpH Setpoint
self.pHLowerLabel = QLabel('Lower pH setpoint: ', self)
font = self.pHLowerLabel.font()
font.setPointSize(10)
self.pHLowerLabel.setFont(font)
self.pHLowerLabel.setGeometry(QtCore.QRect(10, 105, 115, 50))
self.pHLowerValue = QLabel('{0:0.2f}'.format(lower_pH), self)
font = self.pHLowerValue.font()
font.setPointSize(10)
self.pHLowerValue.setFont(font)
self.pHLowerValue.setGeometry(QtCore.QRect(120, 105, 50, 50))
#display upper pH setpoint
self.pHUpperLabel = QLabel('Upper pH setpoint: ', self)
font = self.pHUpperLabel.font()
font.setPointSize(10)
self.pHUpperLabel.setFont(font)
self.pHUpperLabel.setGeometry(QtCore.QRect(10, 120, 115, 50))
self.pHUpperValue = QLabel('{0:0.2f}'.format(upper_pH), self)
font = self.pHUpperValue.font()
font.setPointSize(10)
self.pHUpperValue.setFont(font)
self.pHUpperValue.setGeometry(QtCore.QRect(120, 120, 50, 50))
#pH button options
self.pHToGraph = QPushButton('Graph pH', self)
self.pHToGraph.move(10,160)
self.pHToGraph.setToolTip('Show pH in live graph')
self.pHToGraph.clicked.connect(self.displaypHGraph)
self.pHSetpointsButton = QPushButton('Update Setpoints', self)
self.pHSetpointsButton.setGeometry(QtCore.QRect(115, 160, 150, 30))
self.pHSetpointsButton.setToolTip('Edit pH Setpoints')
self.pHSetpointsButton.clicked.connect(self.reactorSetpoints)
self.DOLabel = QLabel('<span style="color:blue"><b>DO:</b></span>',self)
font = self.DOLabel.font()
font.setPointSize(22)
self.DOLabel.setFont(font)
self.DOLabel.setGeometry(QtCore.QRect(10,175,100,100))
self.currentDO = QLabel('<b>' + str(current_DO) + ' mg/L</b>', self)
font = self.currentDO.font()
font.setPointSize(22)
self.currentDO.setFont(font)
self.currentDO.setGeometry(QtCore.QRect(60,175,150,100))
self.DOLowerLabel = QLabel('Lower DO setpoint: ', self)
font = self.DOLowerLabel.font()
font.setPointSize(10)
self.DOLowerLabel.setFont(font)
self.DOLowerLabel.setGeometry(QtCore.QRect(10, 225, 115, 50))
self.DOLowerValue = QLabel('{0:0.2f}'.format(lower_DO) + ' mg/L', self)
font = self.DOLowerValue.font()
font.setPointSize(10)
self.DOLowerValue.setFont(font)
self.DOLowerValue.setGeometry(QtCore.QRect(120, 225, 75, 50))
self.DOToGraph = QPushButton('Graph DO', self)
self.DOToGraph.move(10,260)
self.DOToGraph.setToolTip('Show DO in live graph')
self.DOToGraph.clicked.connect(self.displaypHGraph)
self.tempLabel = QLabel('<span style="color:blue"><b>Temperature:</b></span>',self)
font = self.tempLabel.font()
font.setPointSize(22)
self.tempLabel.setFont(font)
self.tempLabel.setGeometry(QtCore.QRect(10,265,190,100))
self.currentTemp = QLabel('<b>' + str(currentTemp) + '\u2103', self)
font = self.currentTemp.font()
font.setPointSize(22)
self.currentTemp.setFont(font)
self.currentTemp.setGeometry(QtCore.QRect(195,265,150,100))
self.currentStatus = QLabel('<b><u>Other Parameters</u><b>', self)
font = self.currentStatus.font()
font.setPointSize(10)
self.currentStatus.setFont(font)
self.currentStatus.setGeometry(QtCore.QRect(10, 325, 200, 50))
self.currentStatus = QLabel('Current Cycle: ' + '<b>' + currentState + '</b>', self)
font = self.currentStatus.font()
font.setPointSize(10)
self.currentStatus.setFont(font)
self.currentStatus.setGeometry(QtCore.QRect(10, 340, 200, 50))
self.currentCycleTime = QLabel('Current Cycle Time (HH:MM:SS): ' + '<b>' + currentCycTime + '</b>', self)
font = self.currentCycleTime.font()
font.setPointSize(10)
self.currentCycleTime.setFont(font)
self.currentCycleTime.setGeometry(QtCore.QRect(10, 355, 250, 50))
self.remaningCycleTime = QLabel('Remaning Cycle Time (HH:MM:SS): ' + '<b>' + remaningCycTime + '</b>', self)
font = self.remaningCycleTime.font()
font.setPointSize(10)
self.remaningCycleTime.setFont(font)
self.remaningCycleTime.setGeometry(QtCore.QRect(10, 370, 275, 50))
self.show()
# just a dummy graph that I got off a tutorial, it works for what
# i need it to do for now
def displaypHGraph(self):
print("Display pH")
self.m = LinePlot(self, width = 16, height = 9)
self.m.setGeometry(QtCore.QRect(300,40,660,370))
self.m.show()
def displayDOGraph(self):
pass
# was playing with how to update labels here. Just a counter
# that counts up the value from the initial
# this will eventually be replaced with sensor inputs
def updatepH(self):
global current_pH
global lower_pH
global upper_pH
current_pH = current_pH + 0.01
display_pH = '{0:0.2f}'.format(current_pH)
if current_pH < lower_pH:
self.currentpH.setText('<span style="color:red"><b>' + str(display_pH) + '</b></span>')
elif current_pH > upper_pH:
self.currentpH.setText('<span style="color:red"><b>' + str(display_pH) + '</b></span>')
else:
self.currentpH.setText('<span style="color:black"><b>' + str(display_pH) + '<b></span>')
# same thing as with the updatepH function except for DO
def updateDO(self):
global current_DO
global lower_DO
current_DO = current_DO + 0.01
display_DO = '{0:0.2f}'.format(current_DO)
if current_DO < lower_DO:
self.currentDO.setText('<span style = "color:red"><b>' + str(display_DO) + ' mg/L</b></span>')
else:
self.currentDO.setText('<span style = "color:black"><b>' + str(display_DO)+ ' mg/L</b></span>')
# popups the reactorSetpoints window to change the setpoints for
# the reactor. This is where I am haiving troubles, the code
# continues before the user can input new setpoints
def reactorSetpoints(self):
exPopup = setpointsPopup(self)
self.updateSetpoints()
# just have it update the one value for now
def updateSetpoints(self):
self.pHUpperValue.setText(str(upper_pH))
# dummy plot, was learning how to put a matplotlib
# it works for now
class LinePlot(FigureCanvas):
def __init__(self, parent=None, width=16, height=9, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding,QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
self.plot()
def plot(self):
data = [6.89,6.90,6.91,6.92,6.93,6.92,6.96,6.99,7.12,7.14,6.98,6.93,7.01,6.90,7.11,7.21,7.13,6.99]
ax = self.figure.add_subplot(111)
ax.plot(data, 'r-')
ax.set_title('pH')
ax.set_xlabel('Time')
ax.set_ylabel('pH Value')
self.draw()
def main():
app = QApplication(sys.argv)
ex = drawMenuBar()
timer = QTimer()
timer.timeout.connect(ex.updatepH)
timer.timeout.connect(ex.updateDO)
timer.start(1000)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
so all of this works, except the only way I can get the label to update is to close out of the setpoints popup and reopen it. What is a good way to update it upon exiting of the popup window?
Thanks.
from pubnub import Pubnub ;
from tkinter import *
Window = Tk()
pubnub = Pubnub(publish_key="pub-c-9997b5b1-da6f-4935-88f7-4d0645bcdf2b",
subscribe_key="sub-c-2bc2a578-776c-11e6-9195-02ee2ddab7fe")
def Callback(message, channel):
Logic.UpdateMessageList(message)
Logic.UpdateMessageDisplay()
Display.DisplayMessage()
def Error(message):
Window.title("PubNub - Error")
def Connect(message):
Window.title("PubNub - Connected")
def Reconnect(message):
Window.title("PubNub - Reconnected")
def Disconnect(message):
Window.title("PubNub - Disconnected")
def SendMessage(event):
message = (Logic.Username, Display.MessageEntry.get())
pubnub.publish("my_channel", message = message)
pubnub.subscribe(channels='my_channel',
callback = Callback,
error = Error,
connect = Connect,
reconnect = Reconnect,
disconnect = Disconnect)
class Logic:
def __init__(self):
self.Username = ""
self.MessageList = ([],[])
self.MessageNumber = 0
self.MaxMessages = 6
def UpdateMessageList(self, message):
self.MessageList[0].append(message[0])
self.MessageList[1].append(message[1])
self.MessageNumber += 1
def UpdateMessageDisplay(self):
self.DisplayList = []
if self.MessageNumber >= (self.MaxMessages + 1):
self.MessageList[0].pop(0)
self.MessageList[1].pop(0)
for Num in range(len(self.MessageList[0])):
for ListNum in range(2):
self.DisplayList.append((self.MessageList[ListNum][Num]))
self.DisplayList.append("\n")
Logic = Logic()
class MainDisplay:
def __init__(self):
Window.geometry("400x400")
Window.resizable(0,0)
self.MessageVar = StringVar()
Window.title("PubNub")
def ScreenOne(self):
Window.bind("<Return>", self.AdvScreenTwo)
self.EasyFrame = Frame(Window)
self.EasyFrame.config(bg = "Grey", height = 400, width = 400)
self.EasyFrame.grid()
self.EasyFrame.place(relx = 0.5, y = 200, anchor = CENTER)
self.UsernameEntry = Entry(self.EasyFrame)
self.UsernameEntry.config(width = 15, bg = "White", fg = "Black")
self.UsernameEntry.grid()
self.UsernameEntry.place(relx = 0.5, y = 200, anchor = CENTER)
UsernameLabel = Label(self.EasyFrame, text = "Enter Username")
UsernameLabel.config(bg = "Grey", bd = 0, font = ("times",13,"bold"), fg = "White")
UsernameLabel.grid()
UsernameLabel.place(relx = 0.5, y = 90, anchor = CENTER)
def AdvScreenTwo(self, event):
Logic.Username = (self.UsernameEntry.get())
Window.unbind("<Return>")
self.EasyFrame.grid_forget()
self.EasyFrame.destroy()
Window.bind("<Return>", SendMessage)
self.ScreenTwo()
def ScreenTwo(self):
self.MessagesParent = Frame(Window)
self.MessagesParent.config(bg = "Grey", height = 400, width = 400)
self.MessagesParent.grid()
self.MessagesParent.place(relx = 0.5, y = 200, anchor = CENTER)
self.MessageEntry = Entry(self.MessagesParent)
self.MessageEntry.config(width = 40, bg = "Grey", fg = "Black")
self.MessageEntry.grid()
self.MessageEntry.place(relx = 0.5, y = 350, anchor = CENTER)
def DisplayMessage(self):
Y = 10
for Item in (Logic.MessageList[0]):
self.TextLabel = Label(Window, text = Item, height = 3, width = 6, font = ("times", 8, "bold"), anchor = "w")
self.TextLabel.grid()
self.TextLabel.place(relx = 0.05, y = Y)
Y += 50
Y = 10
for Item in (Logic.MessageList[1]):
self.TextLabel = Label(Window, text = Item, height = 3, width = 40, font = ("times", 8, "bold"),wraplength = 270, anchor = "w")
self.TextLabel.grid()
self.TextLabel.place(relx = 0.2, y = Y)
Y += 50
Display = MainDisplay()
def Main():
Display.ScreenOne()
if __name__ == "__main__":
Main()
Window.mainloop()
This is my code which does work when i run it through the console or IDLE which is fine and all but i would like to compile it. I managed to compile it with my usual method using cx_freeze but i get a error message:
OsError: Cannot load native module 'Cryptodome.Cipher,_raw_ecb'
Can provide any additional information that may be required.
Has gotten a fair amount of views so i thought i would post the answer, i emailed pubnub support
Hi Joshua,
Please use this branch from our SDK https://github.com/pubnub/python/tree/reduce_crypto ; it has cryto unbundled from the dependencies.
This fixed it :) (Replace the pubnub file in Pythonx.x with the pubnub.py file on the git)
I need to clear window before I load a new map. But menu buttons have to stay. I was trying self.frame.destroy(), but it kill my menu buttons too. Basically I need to clear class Sokoban, but this class is not in class Window. Problem is in def map1(self): and def map2(self):
import tkinter
from tkinter import *
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title('Sokoban')
self.pack(fill = BOTH, expand = 1)
menu = Menu(self.master)
self.master.config(menu=menu)
file = Menu(menu)
file.add_command(label='Mapa1', command = self.map1)
menu.add_cascade(label='Mapy', menu=file)
edit = Menu(menu)
edit.add_command(label='Mapa2', command = self.map2)
menu.add_cascade(label='Edit', menu=edit)
def map1(self):
self.frame.forget()
Sokoban('map1.txt')
def map2(self):
self.frame.forget()
Sokoban('map2.txt')
class Sokoban:
def __init__(self, subor):
t = open(subor, 'r')
self.pole = [None] * 8
self.box = []
for a in range(8):
self.pole[a] = list(t.readline().strip())
for b in range(len(self.pole[a])):
if self.pole[a][b] == '$':
self.player = Player(a,b)
self.pole[a][b] = '.'
if self.pole[a][b] == '#':
self.box.append(Box(a,b))
self.pole[a][b] = '.'
t.close()
self.game = self.g = tkinter.Canvas(bg = 'white', width = 650, height = 240,
cursor = 'cross')
self.g.pack()
self.farba = [['gray'],['khaki'],['#FF4500'],['yellow'],['brown']]
stena = '*'
policko = '.'
player = '$'
box = '#'
ciel = '+'
## self.newButt = self.g.create_rectangle(511, 0, 650, 45, fill = 'red')
## self.newButtText = self.g.create_text(580.5, 22.5, text = 'New Game',
## font = 'arial 19 italic bold',
## fill = 'yellow')
## self.map1Butt = self.g.create_rectangle(511, 46, 650, 86, fill = 'red')
## self.map1ButtText = self.g.create_text(580.5, 66, text = 'Map - 1',
## font = 'arial 19 italic bold',
## fill = 'yellow')
## self.map2Butt = self.g.create_rectangle(511, 87, 650, 127, fill = 'red')
## self.map2ButtText = self.g.create_text(580.5, 109, text = 'Map - 2',
## font = 'arial 19 italic bold',
## fill = 'yellow')
## self.map3Butt = self.g.create_rectangle(511, 128, 650, 168, fill = 'red')
## self.map3ButtText = self.g.create_text(580.5, 148, text = 'Map - 3',
## font = 'arial 19 italic bold',
## fill = 'yellow')
self.kresli()
self.g.bind_all('<Up>', self.up)
self.g.bind_all('<Down>', self.down)
self.g.bind_all('<Left>', self.left)
self.g.bind_all('<Right>', self.right)
## self.g.bind('<1>', self.Buttons)
def up(self, e):
self.move(-1, 0)
def down(self, e):
self.move(1, 0)
def left(self, e):
self.move(0, -1)
def right(self, e):
self.move(0, 1)
## def newGame(self):
## self.game.pack_forget()
## Sokoban()
## def map1(self):
## self.game.pack_forget()
## Sokoban('map1.txt')
##
## def map2(self):
## self.game.pack_forget()
## Sokoban('map2.txt')
## def Buttons(self, e):
## if '<1>' and self.newButt:
## self.newGame()
## if '<1>' and self.map1Butt:
## self.map1()
##
## if '<1>' and self.map2Butt:
## self.map2()
def kresli(self):
for a in range(8):
for b in range(17):
x,y = b*30, a*30
f = self.farba['*.+'.index(self.pole[a][b])]
self.g.create_rectangle(x,y,x+30,y+30,fill=f)
self.player.kresli(self.g, self.farba[3])
for box in self.box:
box.kresli(self.g, self.farba[4])
def setBox(self, r, s):
for a in range(len(self.box)):
if self.box[a].r==r and self.box[a].s==s:
return a
return -1
def move(self, dr, ds):
r = self.player.r + dr
s = self.player.s + ds
if r<0 or r>=8 or s<0 or s>=510 or self.pole[r][s] == '*':
return
c = self.setBox(r, s)
if c >= 0:
rr = r + dr
ss = s + ds
if rr < 0 or rr>=8 or ss<0 or ss>=510 or self.pole[rr][ss] == '*':
return
if self.setBox(rr, ss) >= 0:
return
self.box[c].move(dr, ds)
self.player.move(dr, ds)
for c in self.box:
if self.pole[c.r][c.s] != '+':
return
class Player:
def __init__(self, r, s):
self.r = r
self.s = s
def kresli(self, g, farba):
self.g = g
x,y = self.s*30, self.r*30
self.plr = tkinter.PhotoImage(file='player.png')
self.id1 = g.create_image(x+15, y+15, image = self.plr)
def move(self, dr, ds):
self.r = self.r + dr
self.s = self.s + ds
self.g.move(self.id1, ds*30, dr*30)
class Box:
def __init__(self, r, s):
self.r = r
self.s = s
def kresli(self, g, farba):
self.g = g
x,y = self.s*30, self.r*30
self.bx = tkinter.PhotoImage(file='box.png')
self.id2 = g.create_image(x+15, y+15, image = self.bx)
def move(self, dr, ds):
self.r = self.r + dr
self.s = self.s + ds
self.g.move(self.id2, ds*30, dr*30)
root = Tk()
root.geometry('510x240')
app = Window(root)
root.mainloop()
Sokoban()
That not-working wall of code is very hard to work with so I will try to answer your menu buttons have to stay part with an example code.
Basically you create two frames, one holds widgets going to be cleared and second one holds other widgets plus first frame.
import tkinter as tk
root = tk.Tk()
root.geometry("300x300")
frame1 = tk.Frame(root)
frame2 = tk.Frame(frame1)
frame1.pack()
frame2.pack()
menubar = tk.Menu(frame1)
menubar.add_command(label="Bring Back!", command=frame2.pack)
menubar.add_command(label="Quit!", command=root.destroy)
tk.Button(frame2, text="Forget only frame2", command=frame2.pack_forget).pack()
tk.Label(frame2, text="Label on frame2").pack()
root.config(menu=menubar)
root.mainloop()