Get row and column when checkbox clicked in QtableView - qtableview

I have a QtableView with data from a file. I added 3 columns with checkboxes, but now I need to know what checkbox is clicked (Row, column, data). This is working for the cell itself but when clicking the checkbox it gives the latest data or if no data it's -1 and None.
I tried to remove a lot of code so I hope this is not to much or to less.
self.model = TableModel([headers, newRows])
self.proxy_model.setSourceModel(self.model)
self.tableView.setModel(self.proxy_model)
self.tableView.clicked.connect(self.cellClicked)
def cellClicked(self):
try:
index = self.tableView.selectionModel().currentIndex()
row = index.row()
col = index.column()
data = index.data()
# print(index.sibling(row,col).data())
if isinstance(data, QtWidgets.QCheckBox):
print(f'Child: {index.child.row()}')
data = data.text()
print(data.isChecked())
print(f'Row:\t{row}\nColumn:\t{col}\nData:\t{data}\n')
except Exception as e:
print(e)
class TableModel(QAbstractTableModel):
def __init__(self, data):
super().__init__()
self.checks = {}
self.headers = data[0]
self.rows = data[1]
def data(self, index, role):
try:
if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.EditRole:
return self.rows[index.row()][index.column()]
elif role == Qt.ItemDataRole.CheckStateRole and (index.column() == 0 or index.column() == 6 or index.column() == 7):
return self.checkState(QPersistentModelIndex(index))
def setData(self, index, value, role = Qt.ItemDataRole.EditRole):
if value is not None and role == Qt.ItemDataRole.EditRole:
self.rows[index.row()][index.column()] = value
# self.dataChanged.emit(index, index)
return True
elif not index.isValid():
return False
elif role == Qt.ItemDataRole.CheckStateRole:
self.checks[QPersistentModelIndex(index)] = value
return True
return False
def checkState(self, index):
if index in self.checks.keys():
return self.checks[index]
else:
return Qt.CheckState.Unchecked
def flags(self, index):
col = index.column()
if col == 0 or col == 6 or col == 7:
return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsUserCheckable
else:
return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable

Related

Programmatic access to SQLModel class attributes

I am trying to plug a SQLModel table onto a dash data table, handling pagination, filtering and page count in the backend, as explained here https://dash.plotly.com/datatable/callbacks
Working code
from sqlmodel import SQLModel
from sqlmodel import select
from sqlmodel import col
from sqlmodel import Session
from typing import Dict
from typing import List
from typing import Tuple
class Foo(SQLModel, table=True):
bara: str
barb: int
filters = {'bara': ('contains ', 'toto'), 'barb': ('>', 1)}
def filter_foos(filters: Dict[str, Tuple[str, str]]):
"""
try to filter foos
"""
query = select(Foo)
if values := filters.get('bara'):
query = query.where(col(Foo.bara).contains(values[1]))
if values := filters.get('barb'):
if values[0] == '>=':
query = query.where(col(Foo.barb) >= values[1])
elif values[0] == '<=':
query = query.where(col(Foo.barb) <= values[1])
elif values[0] == '!=':
query = query.where(col(Foo.barb) != values[1])
elif values[0] == '=':
query = query.where(col(Foo.barb) == values[1])
elif values[0] == '>':
query = query.where(col(Foo.barb) > values[1])
elif values[0] == '<':
query = query.where(col(Foo.barb) < values[1])
return query
def select_relevant_db_lines(
session: Session,
limit: int,
offset: int,
filters: Dict[str, Tuple[str, str]]
) -> List:
"""
Select relevant row lines from Foo.
"""
if limit is not None and offset is not None:
return list(session.exec(filter_foos(filters).offset(offset*limit).limit(limit)))
My issue is that the filter function is awefully ugly, and not modular at all. If I have an new class
class Fooo(SQLModel, table=True):
toto: str
titi: int
tutu: int
I will hand up redoing the same filter_foos boiler plate code
What I would like would be to have a dictionary to access Foo class attributes, something like (pseudo-code, does not wok)
foo_attributes: Dict = {
'bara': Foo.bara
'barb': Foo.barb
}
That way I can dissociate the generic str int datetime and whatnot treatment and then map them on class attributes. Something like (pseudo-code, not working)
def filter_ints(query, model_field: ???, operator: str, value: int):
"""
try to filter ints
"""
if not operator or not value:
return query
if operator == '>=':
query = query.where(col(model_field) >= value)
elif operator == '<=':
query = query.where(col(model_field) <= value)
elif operator == '!=':
query = query.where(col(model_field) != value)
elif operator == '=':
query = query.where(col(model_field) == value)
elif operator == '>':
query = query.where(col(model_field) > value)
elif operator == '<':
query = query.where(col(model_field) < value)
return query
def filter_strs(query, model_field: ???, value: int):
"""
try to filter strs
"""
if not value:
return query
query = query.where(col(model_field).contains(value))
def filter_models(model: Any, filters: Dict[str, Tuple[str, str]]):
"""
try to filter any model
"""
query = select(model)
if not filters:
return query
for key, (operator, value) in filters:
update_query(query, model, key, operator, value)
Is it possible to do such a thing, or will I have to implement one ugly method after another each time I add a new table to show in my dash app?

Remove line of text from a Json file

I am programming an economic bot with items, inventory, currency and much more, but now when I sell my item in my inventory it is still there in the embed, but I want that when I sell my item and the number in the inventory is 0 that this is then no longer displayed in the inventory embed, so to speak, is removed from the Json file
My code for the sell command:
#client.command()
async def sell(ctx,item,amount = 1):
await open_account(ctx.author)
res = await sell_this(ctx.author,item,amount)
em1 = discord.Embed(title=f"{ctx.author.name}",
description="Das item konnte nicht in deinem Inventar gefunden werden",
color=0xe67e22)
em1.set_thumbnail(url=ctx.author.avatar_url)
em2 = discord.Embed(title=f"{ctx.author.name}",
description=f"Du hast keine {amount} {item} in deinem inventar",
color=0xe67e22)
em2.set_thumbnail(url=ctx.author.avatar_url)
em3 = discord.Embed(title=f"{ctx.author.name}",
description=f"Du hast das Item: **{item}** nicht in deinem Inventar",
color=0xe67e22)
em3.set_thumbnail(url=ctx.author.avatar_url)
em4 = discord.Embed(title=f"{ctx.author.name}",
description=f"Du hast {amount} {item} gekauft",
color=0xe67e22)
em4.set_thumbnail(url=ctx.author.avatar_url)
if not res[0]:
if res[1]==1:
await ctx.send(embed=em1)
return
if res[1]==2:
await ctx.send(embed=em2)
return
if res[1]==3:
await ctx.send(embed=em3)
return
await ctx.send(embed=em4)
async def sell_this(user,item_name,amount,price = None):
item_name = item_name.lower()
name_ = None
for item in mainshop:
name = item["name"].lower()
if name == item_name:
name_ = name
if price==None:
price = 0.9* item["price"]
break
if name_ == None:
return [False,1]
cost = price*amount
users = await get_bank_data()
bal = await update_bank(user)
try:
index = 0
t = None
for thing in users[str(user.id)]["bag"]:
n = thing["item"]
if n == item_name:
old_amt = thing["amount"]
new_amt = old_amt - amount
if new_amt < 0:
return [False,2]
users[str(user.id)]["bag"][index]["amount"] = new_amt
t = 1
break
index+=1
if t == None:
return [False,3]
except:
return [False,3]
with open("Bank.json","w") as f:
json.dump(users,f)
await update_bank(user,cost,"wallet")
return [True,"Worked"]
I hope someone can help me
Use del to delete the item in question from the json data:
try:
index = 0
t = None
for thing in users[str(user.id)]["bag"]:
n = thing["item"]
if n == item_name:
old_amt = thing["amount"]
new_amt = old_amt - amount
if new_amt < 0:
return [False,2]
elif new_amt == 0: # Check if amount is 0
del users[str(user.id)]["bag"][index] # Delete item from bag
else:
users[str(user.id)]["bag"][index]["amount"] = new_amt
t = 1
break
index+=1
if t == None:
return [False,3]
except:
return [False,3]
This completely removes the item and amount from the 'bag'.

Using Pynput listener to pause and continue a script

So I've got this:
from pynput.keyboard import Key, Controller, Listener
keyboard = Controller()
import random
import time
def mainfunction():
key1 = input("type first key to be repeated: ")
key2 = input("second.. : ")
key3 = input("last .. : ")
x = 0
while x < 10000:
keyboard.press(key1)
keyboard.release(key1)
time.sleep((random.randint(1, 8))/10)
keyboard.press(key2)
keyboard.release(key2)
time.sleep((random.randint(1, 8))/10)
keyboard.press(key3)
keyboard.release(key3)
time.sleep((random.randint(1, 8))/10)
x = x + 1
mainfunction()
and I want it to pause and continue on the double press of some arbitrary letter but have no clue how to go about it using pynput.listener.
from pynput.keyboard import Key, Controller, Listener
keyboard = Controller()
from threading import Thread
import random
import time
def listen(key):
global keyletter
global key4
keydata = str(key)
try:
if keydata.replace("'", "") == str(key4):
keyletter = keydata.replace("'", "")
except:
#at Programstart key4 is not defined jet and would lead to an Error
pass
def mainThread():
global keyletter
global key4
key1 = input("type first key to be repeated: ")
key2 = input("second.. : ")
key3 = input("last.. : ")
key4 = input("interrupt.. ")
bool_interrupt = False
x = 0
while x < 10000:
if keyletter == str(key4):
if bool_interrupt == False:
bool_interrupt = True
time.sleep(0.5)
keyletter = ""
else:
bool_interrupt = False
time.sleep(0.5)
keyletter = ""
if bool_interrupt == False:
keyboard.press(key1)
keyboard.release(key1)
time.sleep((random.randint(1, 8))/10)
keyboard.press(key2)
keyboard.release(key2)
time.sleep((random.randint(1, 8))/10)
keyboard.press(key3)
keyboard.release(key3)
time.sleep((random.randint(1, 8))/10)
x = x + 1
def listenerThread():
global keyletter
keyletter = ""
with Listener(on_press=listen) as l:
l.join()
myThread1 = Thread(target=mainThread)
myThread2 = Thread(target=listenerThread)
myThread1.start()
myThread2.start()
This might be overcomplicated, but it works.
i use a second Thread, since the Listener stops the Code until Input.
This way, the mainThread loops, while the listenerThread waits for an Input.

How to add extra fields in ValueQuerySet (Django)?

Basically, I want to convert the query_set to JSON. But I also want to add one more field something like size = some number in the query_set which is not present in the query_set attributes (it is computed attribute). Can you tell me how to do it?
query_set = PotholeCluster.objects.all().values('bearing', 'center_lat', 'center_lon', 'grid_id')
return JsonResponse(list(query_set), safe=False)
I tried the code below. It works, but I would like to know if there is any cleaner way to do this.
query_set = PotholeCluster.objects.all()
response_list = []
for pc in query_set:
d = {}
d['bearing'] = pc.get_bearing()
d['center_lat'] = pc.center_lat
d['center_lon'] = pc.center_lat
d['grid_id'] = pc.grid_id
d['size'] = pc.pothole_set.all().count()
response_list.append(d)
serialized = json.dumps(response_list)
return HttpResponse(serialized, content_type='application/json')
class PotholeCluster(models.Model):
center_lat = models.FloatField(default=0)
center_lon = models.FloatField(default=0)
snapped_lat = models.FloatField(default=0)
snapped_lon = models.FloatField(default=0)
size = models.IntegerField(default=-1)
# avgspeed in kmph
speed = models.FloatField(default=-1)
# in meters
accuracy = models.FloatField(default=-1)
# avg bearing in degree
bearing = models.FloatField(default=-1)
grid = models.ForeignKey(
Grid,
on_delete=models.SET_NULL,
null=True,
blank=True
)
def __str__(self):
raw_data = serialize('python', [self])
output = json.dumps(raw_data[0]['fields'])
return "pk = {}|{}".format(self.id, output)
def get_bearing(self):
if self.bearing != -1:
return self.bearing
potholes = self.pothole_set.all()
bearings = [pothole.location.bearing for pothole in potholes]
bearings.sort()
i = 0
if bearings[-1] >= 350:
while bearings[-1] - bearings[i] >= 340:
if bearings[i] <= 10:
bearings[i] += 360
i += 1
self.bearing = sum(bearings) / len(bearings) % 360
self.save()
return self.bearing
def get_size(self):
if self.size != -1:
return self.size
self.size = len(self.pothole_set.all())
self.save()
return self.size

Support with Logic Gate Simulation program in Python

I'm trying to create a logic gate simulation program in python so that a user can choose the type of logic gate they want to simulate. Once chosen, they can then enter the inputs and the program should return the value of the output from the chosen logic gate to the user.
This is what I have so far:
print ("Logic Gate Simulation")
def AND (a,b):
if a == 1 and b == 1:
return 1
else:
return 0
def NAND (a,b):
if a == 1 and b == 1:
return 0
else:
return 1
def OR(a,b):
if a == 1:
return 1
elif b == 1:
return 1
else:
return 0
def NOR (a,b):
if a != b:
return 1
else:
return 1
def Main():
question = input("what type of gate do you want to simulate - OR, AND or NAND? ")
if question == 'AND':
a = input("enter value for input 1")
b = input("enter value for input 2")
x= AND(a,b)
print (x)
else:
print ("")
Main()
When I run the program and enter AND, inputs 1 and 1 it still returns 0 and I cant see why.
this works:
def AND (a,b):
a=int(a)
b=int(b)
if a == 1 and b == 1:
return 1
else:
return 0
you have to tell python that a and b are integers - (there are better ways of doing that than the method shown)
This is my version of the code (I had to this for homework for AS Level, this may help you!) :
print("Logic Gate Calculator")
def AND(a, b): # AND Gate
a = int(a)
b = int(b)
if a == 1 and b == 1: # AND Gate logic
return 1
else:
return 0
def NAND(a, b): # NAND Gate
a = int(a)
b = int(b)
if a == 1 and b == 1: # NAND Gate logic
return 0
elif a == 1 and b == 0:
return 0
elif a == 0 and b == 1:
return 0
else:
return 1
def OR(a, b): # OR Gate
a = int(a)
b = int(b)
if a == 1: # OR Gate Logic
return 1
elif b == 1:
return 1
else:
return 0
def NOR(a, b): # NOR Gate
a = int(a)
b = int(b)
if a == 1 and b == 0: # NOR Gate Logic
return 1
elif a == 0 and b == 1:
return 1
elif a == 0 and b == 0:
return 1
else:
return 0
def XOR(a, b): # XOR Gate
a = int(a)
b = int(b)
if a == 1 and b == 0: # XOR Gate Logic
return 1
elif a == 1 and b == 1:
return 1
else:
return 0
def main(): # The main program
run = True
while run: # While loop
question = input("What type of gate do you want to use OR, AND, NOR, or NAND or (Q)uit") # Logic Gate chooser
if question == "AND" or question == "and" or question == "And": # If the user selects AND
a = input("Enter value for input 1 (1 or 0):") # Getting the Logic Gate's 1st input
b = input("Enter value for input 2 (1 or 0):") # Getting the Logic Gate's 2nd input
x = AND(a, b) # Calling the AND Function
print("The output will be:", x) # Output result
elif question == "OR" or question == "or" or question == "Or": # If the user selects OR
a = input("Enter value for input 1 (1 or 0):") # Getting the Logic Gate's 1st input
b = input("Enter value for input 2 (1 or 0):") # Getting the Logic Gate's 2nd input
x = OR(a, b) # Calling the OR Function
print("The output will be:", x) # Output result
elif question == "NOR" or question == "nor" or question == "Nor": # If the user selects NOR
a = input("Enter value for input 1 (1 or 0):") # Getting the Logic Gate's 1st input
b = input("Enter value for input 2 (1 or 0):") # Getting the Logic Gate's 2nd input
x = NOR(a, b) # Calling the NOR function
print("The output will be:", x) # Output result
elif question == "NAND" or question == "nand" or question == "Nand": # If the user selects NAND
a = input("Enter value for input 1 (1 or 0):") # Getting the Logic Gate's 1st input
b = input("Enter value for input 2 (1 or 0):") # Getting the Logic Gate's 2nd input
x = NAND(a, b) # Calling the NAND function
print("The output will be:", x) # Output result
elif question == "XOR" or question == "xor" or question == "Xor": # If the user selects XOR
a = input("Enter value for input 1 (1 or 0):") # Getting the Logic Gate's 1st input
b = input("Enter value for input 2 (1 or 0):") # Getting the Logic Gate's 2nd input
x = XOR(a, b) # Calling the XOR function
print("The output will be:", x) # Output result
elif question == "Q" or question == "q": # Quiting the program
run = False
else:
print("Please enter one of the shown logic gates") # Error handling
main()
a=True
b=True
output=a and b
print (output)
a=True
b=False
output=a and b
print (output)
Please try this
It works. Use
if a == 1:
if b == 1:
return 1
else
return 0