QTableWidget.setCellWidget creates windows of the given widget while using multi threading - multithreading

So this code loads all the data from database and puts it in my table and works perfectly fine
it gets the data.
and if it is a combobox uses setCellWidget, and for normal text uses setItem:
output = LoadData(sql)
if output == []:
return False
for row in output:
row_pos = self.table.rowCount()
self.table.insertRow(row_pos)
for i, column in enumerate(row, 0):
normal_widget_item = True
item = QtWidgets.QTableWidgetItem(str(column))
# The 12 col is always a combobox
if i == 12:
item = QtWidgets.QComboBox()
item.addItems(self.all_messager_types)
item.setCurrentIndex(self.all_messager_types.index(column))
normal_widget_item = False
if i == 15:
flags = QtCore.Qt.ItemFlags()
flags != QtCore.Qt.ItemIsEnabled
item.setFlags(flags)
if normal_widget_item:
self.table.setItem(row_pos, i, item)
else:
self.table.setCellWidget(row_pos,i,item)
self.table.resizeColumnsToContents()
but when I try to use it in a different thread it creates new windows for every widget.
my thread class:
class load_table_thread(threading.Thread):
def __init__(self,target,sql=""):
super().__init__()
self.sql = sql
self.target = target
def run(self):
output = LoadData(self.sql)
if output == []:
return False
for row in output:
row_pos = self.target.table.rowCount()
self.target.table.insertRow(row_pos)
for i, column in enumerate(row, 0):
normal_widget_item = True
item = QtWidgets.QTableWidgetItem(str(column))
if i == 12:
item = QtWidgets.QComboBox()
item.addItems(self.target.all_messager_types)
item.setCurrentIndex(self.target.all_messager_types.index(column))
normal_widget_item = False
if i == 15:
flags = QtCore.Qt.ItemFlags()
flags != QtCore.Qt.ItemIsEnabled
item.setFlags(flags)
if normal_widget_item:
self.target.table.setItem(row_pos, i, item)
else:
self.target.table.setCellWidget(row_pos,i,item)
self.target.table.resizeColumnsToContents()
and this is the way I call it:
th = load_table_thread(self,sql)
th.start()
there is not errors in runtime but the program creates new windows for every combo box ( ignore the text, just look how many windows are open for the combobox ):
See the issue image
I used the pyqt threading system too but the same problem happens.

Related

python script for 4x4 keypad, some buttons not workin

I'm trying to use a python script to make a connection with my 4x4 keypad on Rastberry (RPi.GPIO).
The code does not work correctly, because the first and second rows does not respond. I'm trying to use pad4pi, but in my case, this not work.
This is the code I'm using in the moment.
(Main Control)
import RPi.GPIO as GPIO
import time
import serial
import Keypad
#import Open_CV
ROWS = 4 # number of rows of the Keypad
COLS = 4 #number of columns of the Keypad
keys = [ '1','2','3','A', #key code
'4','5','6','B',
'7','8','9','C',
'*','0','#','D' ]
rowsPins = [18,22,29,31] #connect to the row pinouts of the keypad
colsPins = [32,33,36,37] #connect to the column pinouts of the keypad
# the pins need to be these, because the others are already in use
# Configure the use of the serial terminal and the baud rate
ser = serial.Serial( #"/dev/ttyS0", 9600)
port='/dev/ttyS0', #Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
baudrate = 9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1)
#ConfiguraĆ§Ć£o inicial dos terminais GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
# call the video method
#video("teste.mp4")
def loop():
keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS) #create Keypad object
keypad.setDebounceTime(50) #set the debounce time
# call the video method
#video('/home/pi/share/teste.mp4')
while(True):
key = keypad.getKey() #obtain the state of keys
if(key != keypad.NULL): #if there is key pressed, print its key code.
print ("You Pressed Key : %c "%(key))
ser.write(str.encode(key))
time.sleep(1)
#ret, frame = cap.read()
#gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#cv2.imshow('frame',gray)
#if cv2.waitKey(1) & 0xFF == ord('q'):
# break
#cap.release()
#cv2.destroyAllWindows()
if __name__ == '__main__': #Program start from here
print ("Program is starting ... ")
try:
loop()
except KeyboardInterrupt: #When 'Ctrl+C' is pressed, exit the program.
GPIO.cleanup()
(keypad functions)
#!/usr/bin/env python3
########################################################################
# Filename : Keypad.py
# Description : The module of matrix keypad
# Author : freenove
# modification: 2016/07/13
########################################################################
import RPi.GPIO as GPIO
import time
#class Key:Define some of the properties of Key
class Key(object):
NO_KEY = '\0'
#Defines the four states of Key
IDLE = 0
PRESSED = 1
HOLD = 2
RELEASED = 3
#define OPEN and CLOSED
OPEN = 0
CLOSED =1
#constructor
def __init__(self):
self.kchar = self.NO_KEY
self.kstate = self.IDLE
self.kcode = -1
self.stateChanged = False
class Keypad(object):
NULL = '\0'
LIST_MAX = 10 #Max number of keys on the active list.
MAPSIZE = 10 #MAPSIZE is the number of rows (times 16 columns)
bitMap = [0]*MAPSIZE
key = [Key()]*LIST_MAX
holdTime = 500 #key hold time
holdTimer = 0
startTime = 0
#Allows custom keymap, pin configuration, and keypad sizes.
def __init__(self,usrKeyMap,row_Pins,col_Pins,num_Rows,num_Cols):
GPIO.setmode(GPIO.BOARD)
self.rowPins = row_Pins
self.colPins = col_Pins
self.numRows = num_Rows
self.numCols = num_Cols
self.keymap = usrKeyMap
self.setDebounceTime(10)
#Returns a single key only. Retained for backwards compatibility.
def getKey(self):
single_key = True
if(self.getKeys() and self.key[0].stateChanged and (self.key[0].kstate == self.key[0].PRESSED)):
return self.key[0].kchar
single_key = False
return self.key[0].NO_KEY
#Populate the key list.
def getKeys(self):
keyActivity = False
#Limit how often the keypad is scanned.
if((time.time() - self.startTime) > self.debounceTime*0.001):
self.scanKeys()
keyActivity = self.updateList()
self.startTime = time.time()
return keyActivity
#Hardware scan ,the result store in bitMap
def scanKeys(self):
#Re-intialize the row pins. Allows sharing these pins with other hardware.
for pin_r in self.rowPins:
GPIO.setup(pin_r,GPIO.IN,pull_up_down = GPIO.PUD_UP)
#bitMap stores ALL the keys that are being pressed.
for pin_c in self.colPins:
GPIO.setup(pin_c,GPIO.OUT)
GPIO.output(pin_c,GPIO.LOW)
for r in self.rowPins: #keypress is active low so invert to high.
self.bitMap[self.rowPins.index(r)] = self.bitWrite(self.bitMap[self.rowPins.index(r)],self.colPins.index(pin_c),not GPIO.input(r))
#Set pin to high impedance input. Effectively ends column pulse.
GPIO.output(pin_c,GPIO.HIGH)
GPIO.setup(pin_c,GPIO.IN)
#Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
def updateList(self):
anyActivity = False
kk = Key()
#Delete any IDLE keys
for i in range(self.LIST_MAX):
if(self.key[i].kstate == kk.IDLE):
self.key[i].kchar = kk.NO_KEY
self.key[i].kcode = -1
self.key[i].stateChanged = False
# Add new keys to empty slots in the key list.
for r in range(self.numRows):
for c in range(self.numCols):
button = self.bitRead(self.bitMap[r],c)
keyChar = self.keymap[r * self.numCols +c]
keyCode = r * self.numCols +c
idx = self.findInList(keyCode)
#Key is already on the list so set its next state.
if(idx > -1):
self.nextKeyState(idx,button)
#Key is NOT on the list so add it.
if((idx == -1) and button):
for i in range(self.LIST_MAX):
if(self.key[i].kchar == kk.NO_KEY): #Find an empty slot or don't add key to list.
self.key[i].kchar = keyChar
self.key[i].kcode = keyCode
self.key[i].kstate = kk.IDLE #Keys NOT on the list have an initial state of IDLE.
self.nextKeyState(i,button)
break #Don't fill all the empty slots with the same key.
#Report if the user changed the state of any key.
for i in range(self.LIST_MAX):
if(self.key[i].stateChanged):
anyActivity = True
return anyActivity
#This function is a state machine but is also used for debouncing the keys.
def nextKeyState(self,idx, button):
self.key[idx].stateChanged = False
kk = Key()
if(self.key[idx].kstate == kk.IDLE):
if(button == kk.CLOSED):
self.transitionTo(idx,kk.PRESSED)
self.holdTimer = time.time() #Get ready for next HOLD state.
elif(self.key[idx].kstate == kk.PRESSED):
if((time.time() - self.holdTimer) > self.holdTime*0.001): #Waiting for a key HOLD...
self.transitionTo(idx,kk.HOLD)
elif(button == kk.OPEN): # or for a key to be RELEASED.
self.transitionTo(idx,kk.RELEASED)
elif(self.key[idx].kstate == kk.HOLD):
if(button == kk.OPEN):
self.transitionTo(idx,kk.RELEASED)
elif(self.key[idx].kstate == kk.RELEASED):
self.transitionTo(idx,kk.IDLE)
def transitionTo(self,idx,nextState):
self.key[idx].kstate = nextState
self.key[idx].stateChanged = True
#Search by code for a key in the list of active keys.
#Returns -1 if not found or the index into the list of active keys.
def findInList(self,keyCode):
for i in range(self.LIST_MAX):
if(self.key[i].kcode == keyCode):
return i
return -1
#set Debounce Time, The defaul29t is 50ms
def setDebounceTime(self,ms):
self.debounceTime = ms
#set HoldTime,The default is 500ms
def setHoldTime(self,ms):
self.holdTime = ms
#
def isPressed(self, keyChar):
for i in range(self.LIST_MAX):
if(self.key[i].kchar == keyChar):
if(self.key[i].kstate == self.self.key[i].PRESSED and self.key[i].stateChanged):
return True
return False
#
def waitForKey(self):
kk = Key()
waitKey = kk.NO_KEY
while(waitKey == kk.NO_KEY):
waitKey = self.getKey()
return waitKey
def getState(self):
return self.key[0].kstate
#
def keyStateChanged(self):
return self.key[0].stateChanged
def bitWrite(self,x,n,b):
if(b):
x |= (1<<n)
else:
x &=(~(1<<n))
return x
def bitRead(self,x,n):
if((x>>n)&1 == 1):
return True
else:
return False

how to can open the .py file like an application on windows?

from tkinter import *
import random
command_list = []
def next_turn(r, c):
global player
global command_list
global game_started
command_list.append((r, c))
if buttons[r][c]['text'] == "" and check_winner() is False:
if player == players[0]:
buttons[r][c]['text'] = player
game_started = True
if check_winner() is False:
player = players[1]
player_label.configure(text=(player + "'s turn"))
elif check_winner() is True:
player_label.configure(text=(player + " WINS!"))
elif check_winner() == 'Tie':
player_label.configure(text='TIE!')
else:
buttons[r][c]['text'] = player
if check_winner() is False:
player = players[0]
player_label.configure(text=(player + "'s turn"))
elif check_winner() is True:
player_label.configure(text=(player + " WINS!"))
elif check_winner() == 'Tie':
player_label.configure(text='TIE!', bg='yellow')
def check_winner():
# rows wise
for r in range(3):
if buttons[r][0]['text'] == buttons[r][1]['text'] == buttons[r][2]['text'] != "":
buttons[r][0].configure(bg='green')
buttons[r][1].configure(bg='green')
buttons[r][2].configure(bg='green')
return True
# column wise
for c in range(3):
if buttons[0][c]['text'] == buttons[1][c]['text'] == buttons[2][c]['text'] != "":
buttons[0][c].configure(bg='green')
buttons[1][c].configure(bg='green')
buttons[2][c].configure(bg='green')
return True
# diagonal wise
if buttons[0][0]['text'] == buttons[1][1]['text'] == buttons[2][2]['text'] != "":
buttons[0][0].configure(bg='green')
buttons[1][1].configure(bg='green')
buttons[2][2].configure(bg='green')
return True
if buttons[0][2]['text'] == buttons[1][1]['text'] == buttons[2][0]['text'] != "":
buttons[0][2].configure(bg='green')
buttons[1][1].configure(bg='green')
buttons[2][0].configure(bg='green')
return True
if empty_space():
return False
return "Tie"
def empty_space():
for r in range(3):
for c in range(3):
if buttons[r][c]['text'] == '':
return True
return False
def new_game():
global player
player = random.choice(players)
player_label.configure(text=player + "'s turn")
for r in range(3):
for c in range(3):
buttons[r][c].configure(text="", bg='grey')
def undo():
global player
if check_winner() is False and len(command_list) != 0:
undo_row, undo_column = command_list[-1][0], command_list[-1][1]
buttons[undo_row][undo_column]['text'] = ''
if player == players[1]:
player = players[0]
player_label.configure(text=(player + "'s turn"))
else:
player = players[1]
player_label.configure(text=(player + "'s turn"))
command_list.pop()
mainWindow = Tk()
mainWindow.title("Tic-Tac-Toe")
mainWindow.configure(background='grey')
players = ["X", "O"]
# pick a random player.
player = random.choice(players)
# end button
end_button = Button(mainWindow, text="Close", background='red', font=('consolas', 20), command=mainWindow.destroy)
end_button.pack(anchor='w')
player_label = Label(mainWindow, text=player + "'s turn", font=('consolas', 40))
player_label.pack(side='top')
reset_button = Button(mainWindow, text='New Game', font=('consolas', 20), command=new_game)
reset_button.pack(side='top')
# undo button
undo_button = Button(mainWindow, text='Undo', font=('consolas', 20), command=undo)
undo_button.pack(side='top', anchor='e')
# Buttons structure
buttons = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
# Game Board.
board = Frame(mainWindow)
board.configure(background='grey')
board.pack()
for row in range(3):
for column in range(3):
buttons[row][column] = Button(board, text="", font=('consolas', 40), width=5, height=2,
command=lambda bt_row=row, bt_column=column:
next_turn(bt_row, bt_column))
buttons[row][column].grid(row=row, column=column)
buttons[row][column].configure(background='grey')
mainWindow.mainloop()
The above program is a game called Tic-Tak-Toe.
I am able to run the program on IDE without any error.
This is the program that i want to run on windows or linux or any other platform without using the IDE or command line, just like other application such as word, execel , halo 3(game) etc. How can I do it ?
You need to target an operating system and create an executable file. For example you could create a c program that calls your .py pgoram. Below is an example of how to do that for windows.
For windows - I used windows Ubuntu linux subsystem to create the executable targeting windows 64-bit:
sudo apt-get install mingw-w64. Read more.
make new file game.c
#include <stdlib.h>
int main() {
system("py ./temp.py");
return 0;
}
Put your game.py and game.c in the same folder and run
x86_64-w64-mingw32-gcc -o game.exe game.c
Working Picture

Tic-tac-toe using python tkinter

Tic-tac-toe game using python tkinter is not working correctly.
Tic-tac-toe structure is correct. I just want to change the click event.
Only button9 output shown when click to any button
Every time I click any button this output is shown
from tkinter import *
bclick = True
tk = Tk()
tk.title("Tic Tac toe")
tk.geometry("300x400")
n = 9
btns = []
def ttt(button):
global bclick
print(button)
if button["text"] == "" and bclick == True:
print("if")
button.config(text="X")
bclick = False
elif button["text"] == "" and bclick == False:
print("else")
button["text"] = "0"
bclick = True
for i in range(9):
btns.append(Button(font=('Times 20 bold'), bg='white', fg='black', height=2, width=4))
row = 1
column = 0
index = 1
print(btns)
buttons = StringVar()
for i in btns:
i.grid(row=row, column=column)
i.config(command=lambda: ttt(i))
print(i, i["command"])
column += 1
if index % 3 == 0:
row += 1
column = 0
index += 1
tk.mainloop()
Common misstake. The lambda function is using the last value assigned to i so every lambda will use i=.!button9. change the lambda function to:
i.config(command=lambda current_button=i: ttt(current_button))
which will make lambda use the value of i when the lambda was created.

Object() takes no arguments

I get, "TypeError: Question() takes no arguments" (where Question is an object of class Question) when trying to execute the code below.
I'm using jupyter notebook and have checked most of my indentation, Tthe class Question has 2 attributes, I have an init method...
Issue is related to the function find_best_split(rows) below.
I have added an image of the error console output here
class Question:
def __init__(self, column, value):
self.column = column
self.value = value
def match(self, example):
val = example[self.column]
if is_numeric(val):
return val >= self.value
else:
return val == self.value
def __repr__(self):
condition = "=="
if is_numeric(self.value):
condition = ">="
return "Is %s %s %s?" % (header[self.column], condition, str(self.value))
def partition(rows, question):
true_rows, false_rows = [], []
for row in rows:
if question.match(row):
true_rows.append(row)
else:
false_rows.append(row)
return true_rows, false_rows
` Error points to this function, specifically "question = Question(col, val)"
def find_best_split(rows):
best_gain = 0
best_question = None
current_uncertainty = gini(rows)
n_features = len(rows[0]) -1 # number of columns
for col in range(n_features):
values = set([row[col] for row in rows]) # unique values in the column
for val in values: #now for each value
question = Question(col, val)
# trying to split the data set
true_rows, false_rows = partition(rows, question)
# skips this split if it doesn't divide the data set.
if len(true_rows) == 0 or len(false_rows) == 0:
continue
# calculate the information gain from this split
gain = info_gain(true_rows, false_rows, current_uncertainty)
# you can use > instead of >= below but I wanted the data set to look a certain way for this example.
if gain >= best_gain:
best_gain, best_question = gain, question
return best_gain, best_quesiton
`
class Decision_Node:
def __init__(self, question, true_branch, false_branch):
self.question = question
self.true_branch = true_branch
self.false_branch = false_branch
def build_tree(rows):
gain, question = find_best_split(rows)
if gain == 0:
return Leaf(rows)
true_rows, false_rows = partition(rows, question)
true_branch = build_tree(true_rows)
false_branch = build_tree(false_rows)
return Decision_Node(question, true_branch, false_branch)
if __name__ == '__main__':
my_tree = build_tree(training_data)
print_tree(my_tree)
# Evaluate
testing_data = [
["Green", 3, "Mango"],
["Yellow", 4, "Mango"],
["Red", 2, "Grape"],
["Red", 1, "Grape"],
["Yellow", 3, "Lemon"],
]
for row in testing_data:
print ("Actual: %s. Predicted: %s" % (row[-1], print_leaf(classify(row, my_tree))))

What is wrong with my elif statement? Invalid Syntax

if option == "1":
with open("sample.txt","r") as f:
print(f.read())
numbers = []
with open("sample2.txt","r") as f:
for i in range(9):
numbers.append(f.readline().strip())
print(numbers)
from random import randint
for i in range(9):
print(numbers[randint(0,8)])
from tkinter import *
def mhello():
mtext = ment.get()
mLabel2 = Label(test, text=mtext).pack()
return
test = Tk()
ment = StringVar()
test.geometry('450x450+500+10')
test.title('Test')
mlabel = Label(test, text='Time to guess').pack()
mbutton = Button(test, text='Click', command = mhello).pack()
mEntry = Entry(test, textvariable=ment).pack()
test.mainloop()
from tkinter import *
def mhello():
my_word = 'HELLO'
mtext = ment.get()
if my_word == mtext:
mLabel2 = Label(test, text='Correct').pack()
else:
mLabel2 = Label(test, text='Incorrect').pack()
return
test = Tk()
ment = StringVar()
test.geometry('450x450+500+300')
test.title('Test')
def label_1():
label_1 = Label(test, text='Hello. Welcome to my game.').pack()
def label_2():
label_2 = Label(test, text='What word am I thinking of?').pack()
button_1 = Button(test, text='Click', command = mhello).pack()
entry_1 = Entry(test, textvariable=ment).pack()
label_1()
test.after(5000, label_2)
test.mainloop()
from tkinter import *
from random import shuffle
game = Tk()
game.geometry('200x200')
game.grid()
game.title("My Game")
board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def board_1():
board1 = []
k = 0
for i in range(3):
for j in range(3):
board1.append(Label(game, text = board[k]))
board1[k].grid(row = i, column = j)
k +=1
def board_2():
shuffle(board)
board2 = []
k = 0
for i in range(3):
for j in range(3):
board2.append(Label(game, text = board[k]))
board2[k].grid(row = i, column = j)
k +=1
board_1()
game.after(5000, board_2)
game.mainloop()
#2nd Option
elif option == "2":
print ("You have chosen option 2. Well Done, You Can Type! XD")
The bit that has the Syntax Error is the 1st elif statement (2nd Option). Ignore all the code prior to this if necessary (it is there for context). Whenever I run the code it says that there is a syntax error and just positions the typing line (I don't know what it's called) at the end of the word elif.
This is a simple fix, with if else statements you need to have a closing ELSE and in this case there is not so when your program runs it sees that theres a lonely if without its else :)
if option == "1":
elif option == "2":
else:
'do something else in the program if any other value was recieved'
also a switch statement can be used here so it does not keep checking each condition and just goes straight to the correct case :D
The problem is that your block is separated from the first if-statement, where it actually belongs to. As it is, it follows the game.mainloop() statement, and adds an unexpected indentation. Try to rearrange your code like so:
if option == "1":
with open("sample.txt","r") as f:
print(f.read())
numbers = []
with open("sample2.txt","r") as f:
for i in range(9):
numbers.append(f.readline().strip())
print(numbers)
from random import randint
for i in range(9):
print(numbers[randint(0,8)])
elif option == "2":
print ("You have chosen option 2. Well Done, You Can Type! XD")
[ Rest of the code ]

Resources