Can I sort a QPainter to be drawn on top on other widgets in PyQt4? - sorting

I'm doing a basic node editor with PyQt4. However I'm stuck with this: The lines linking nodes are drawn behind of the widgets when it should be in the reverse order.
Is there a way to force this or should I restart from scratch and try another approach?
The attacahed code should work and give you 2 nodes that you can move. The line linking them is drawn behind of everything instead of on top.
Thank you
from PyQt4 import QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtCore import Qt
import sys
class Connector():
def __init__(self, name="", id=id, data=None, connected=None, isInput=True, index=-1, parent=None):
self.id = id
self.name = name
self.data = data
self.parent = parent
self.isConnected = not connected
self.connectedTo = connected
self.isInput = isInput
self.index = index
self.width = 16
self.height = 16
self.upperMargin = 30
def getAbsPosition(self):
return QPoint(self.parent.pos().x()+self.getPosition().x(), self.parent.pos().y() + self.getPosition().y())
def getPosition(self):
if self.parent:
if self.isInput:
deltaX = 0 + self.width / 2
else:
deltaX = self.parent.width() - self.width
deltaY = self.upperMargin + (self.index * self.height*2)
pos = QPoint(deltaX, deltaY)
else:
pos = QPoint(0, 0)
return pos
class Node(QLineEdit ):
def __init__(self,parent=None, name=""):
QLineEdit.__init__(self,parent)
self.size = QSize(200, 300)
self.setText(name)
self.resize(self.size.width(), self.size.height())
self.connectors = []
self.createInputConnector()
self.createOutputConnector()
def getConnectors(self):
return self.connectors
def getNewConnectorIndex(self):
indexInputs = 0
indexOutputs = 0
for connector in self.connectors:
if connector.isInput:
indexInputs += 1
else:
indexOutputs += 1
return indexInputs, indexOutputs
def createConnector(self, name, isInput, index):
newConnector = Connector(name=name, isInput=isInput, index=index, parent=self)
self.connectors.append(newConnector)
return newConnector
def createInputConnector(self, name=""):
index, ignore = self.getNewConnectorIndex()
newConnector = self.createConnector(name, isInput=True, index=index)
return newConnector
def createOutputConnector(self, name=""):
ignore, index = self.getNewConnectorIndex()
newConnector = self.createConnector(name, isInput=False, index=index)
return newConnector
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.path = QPainterPath()
# disabling next line "solves" the problem but not really.
painter.setBrush(QColor(122, 163, 39))
painter.path.addRoundRect(2,2, self.size.width()-6,self.size.height()-6,20,15)
painter.drawPath(painter.path)
for connector in self.connectors:
pos = connector.getPosition()
cx = pos.x()
cy = pos.y()
cw = connector.width
ch = connector.height
painter.drawEllipse(cx, cy, cw, ch)
painter.end()
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
super(Node, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
currPos = self.mapToGlobal(self.pos())
globalPos = event.globalPos()
diff = globalPos - self.__mouseMovePos
newPos = self.mapFromGlobal(currPos + diff)
self.move(newPos)
self.__mouseMovePos = globalPos
super(Node, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return
super(Node, self).mouseReleaseEvent(event)
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.resize(640,480)
self.entry1 = Node(self, "NODE1")
self.entry2 = Node(self, "NODE2")
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
qp.setClipping(False)
self.doDrawing(qp)
qp.end()
self.update()
def doDrawing(self, qp):
p1 = self.entry1.getConnectors()[0].getAbsPosition()
p2 = self.entry2.getConnectors()[0].getAbsPosition()
qp.drawLine(p1.x(),p1.y(), p2.x(), p2.y())
if __name__=="__main__":
app=QApplication(sys.argv)
win=Window()
win.show()
sys.exit(app.exec_())

Related

Fine tuning Bert for NER attempt on Mac OS

I'm using a MacBook Air/OS Monterey 12.5 (There are updates available; Ventura 13.1
Python version 3.10.8 and also tried using 3.11
Pylance has pointed that all the imports I was trying to execute were not being resolved so I changed the VS Code interpreter to Python 3.10.
Anyways, here's the code:
import pandas as pd
import torch
import numpy as np
from tqdm import tqdm
from transformers import BertTokenizerFast
from transformers import BertForTokenClassification
from torch.utils.data import Dataset, DataLoader
df = pd.read_csv('ner.csv')
labels = [i.split() for i in df['labels'].values.tolist()]
unique_labels = set()
for lb in labels:
[unique_labels.add(i) for i in lb if i not in unique_labels]
# print(unique_labels)
labels_to_ids = {k: v for v, k in enumerate(sorted(unique_labels))}
ids_to_labels = {v: k for v, k in enumerate(sorted(unique_labels))}
# print(labels_to_ids)
text = df['text'].values.tolist()
example = text[36]
#print(example)
tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')
text_tokenized = tokenizer(example, padding='max_length', max_length=512, truncation=True, return_tensors='pt')
'''
print(text_tokenized)
print(tokenizer.decode(text_tokenized.input_ids[0]))
'''
def align_label_example(tokenized_input, labels):
word_ids = tokenized_input.word_ids()
previous_word_idx = None
label_ids = []
for word_idx in word_ids:
if word_idx is None:
label_ids.append(-100)
elif word_idx != previous_word_idx:
try:
label_ids.append(labels_to_ids[labels[word_idx]])
except:
label_ids.append(-100)
else:
label_ids.append(labels_to_ids[labels[word_idx]] if label_all_tokens else -100)
previous_word_idx = word_idx
return label_ids;
label = labels[36]
label_all_tokens = False
new_label = align_label_example(text_tokenized, label)
'''
print(new_label)
print(tokenizer.convert_ids_to_tokens(text_tokenized['input_ids'][0]))
'''
def align_label(texts, labels):
tokenized_inputs = tokenizer(texts, padding='max_length', max_length=512, truncation=True)
word_ids = tokenized_inputs.word_ids()
previous_word_idx = None
label_ids = []
for word_idx in word_ids:
if word_idx is None:
label_ids.append(-100)
elif word_idx != previous_word_idx:
try:
label_ids.append(labels_to_ids[labels[word_idx]])
except:
label_ids.append(-100)
else:
try:
label_ids.append(labels_to_ids[labels[word_idx]] if label_all_tokens else -100)
except:
label_ids.append(-100)
previous_word_idx = word_idx
return label_ids
class DataSequence(torch.utils.data.Dataset):
def __init__(self, df):
lb = [i.split() for i in df['labels'].values.tolist()]
txt = df['text'].values.tolist()
self.texts = [tokenizer(str(i),
padding='max_length', max_length=512, truncation=True, return_tensors='pt') for i in txt]
self.labels = [align_label(i,j) for i,j in zip(txt, lb)]
def __len__(self):
return len(self.labels)
def get_batch_labels(self, idx):
return torch.LongTensor(self.labels[idx])
def __getitem__(self, idx):
batch_data = self.get_batch_data(idx)
batch_labels = self.get_batch_labels(idx)
return batch_data, batch_labels
df = df[0:1000]
df_train, df_val, df_test = np.split(df.sample(frac=1, random_state=42),
[int(.8 * len(df)), int(.9 * len(df))])
class BertModel(torch.nn.Module):
def __init__(self):
super(BertModel, self).__init__()
self.bert = BertForTokenClassification.from_pretrained('bert-base-cased', num_labels=len(unique_labels))
def forward(self, input_id, mask, label):
output = self.bert(input_ids=input_id, attention_mask=mask, labels=label, return_dict=False)
return output
def train_loop(model, df_train, df_val):
train_dataset = DataSequence(df_train)
val_dataset = DataSequence(df_val)
train_dataloader = DataLoader(train_dataset, num_workers=4, batch_size=BATCH_SIZE, shuffle=True)
val_dataloader = DataLoader(val_dataset, num_workers=4, batch_size=BATCH_SIZE)
use_cuda = torch.cuda.is_available()
device = torch.device('cuda' if use_cuda else 'cpu')
optimizer = torch.optim.SGD(model.parameters(), lr=LEARNING_RATE)
if use_cuda:
model = model.cuda()
best_acc = 0
best_loss = 1000
for epoch_num in range(EPOCHS):
total_acc_train = 0
total_loss_train = 0
model.train()
for train_data, train_label in tqdm(train_dataloader):
train_label = train_label.to(device)
mask = train_data['attention_mask'].squeeze(1).to(device)
input_id = train_data['input_ids'].squeeze(1).to(device)
optimizer.zero_grad()
loss, logits = model(input_id, mask, train_label)
for i in range(logits.shape[0]):
logits_clean = logits[i][train_label[i] != -100]
label_clean = train_label[i][train_label[i] != -100]
predictions = logits_clean.argmax(dim=1)
acc = (predictions == label_clean).float().mean()
total_acc_train += acc
total_loss_train += loss.item()
loss.backward()
optimizer.step()
model.eval()
total_acc_val = 0
total_loss_val = 0
for val_data, val_label in val_dataloader:
val_label = val_label.to(device)
mask = val_data['attention_mask'].squeeze(1).to(device)
input_id = val_data['input_ids'].squeeze(1).to(device)
loss, logits = model(input_id, mask, val_label)
for i in range(logits.shape[0]):
logits_clean = logits[i][val_label[i] != -100]
label_clean = val_label[i][val_label[i] != -100]
predictions = logits_clean.argmax(dim=1)
acc = (predictions == label_clean).float().mean()
total_acc_val += acc
total_loss_val += loss.item()
val_accuracy = total_acc_val / len(df_val)
val_loss = total_loss_val / len(df_val)
print(
f'Epochs: {epoch_num + 1} | Loss: {total_loss_train / len(df_train): .3f} | Accuracy: {total_acc_train / len(df_train): .3f} | Val_Loss: {total_loss_val / len(df_val): .3f} | Accuracy: {total_acc_val / len(df_val): .3f}')
LEARNING_RATE = 5e-3
EPOCHS = 5
BATCH_SIZE = 2
model = BertModel()
train_loop(model, df_train, df_val)
And the debugger says:
Exception has occurred: RuntimeError (note: full exception trace is shown but execution is paused at: <module>)
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
File "/Users/filipedonatti/Projects/pyCodes/second_try.py", line 141, in train_loop
for train_data, train_label in tqdm(train_dataloader):
File "/Users/filipedonatti/Projects/pyCodes/second_try.py", line 197, in <module>
train_loop(model, df_train, df_val)
File "<string>", line 1, in <module> (Current frame)
By the way,
Despite using Mac, I have downloaded Anaconda-Navigator, however I've been trying and executing this code on VS Code. I've downloaded numpy, torch, datasets and other libraries through Brew with the pip3 command.
I'm at a loss, I can run the code on a google collab notebook or Jupiter notebook, and I know training models and such in my humble Mac would not be advised, but I am just exercising this so I can train and use the model in a much more powerful machine.
Please help me with this issue, I've been trying to find a solution for days.
Peace and happy holidays.
I've tried solving the issue by writing:
if __name__ == '__main__':
freeze_support()
I've tried using this:
import parallelTestModule
extractor = parallelTestModule.ParallelExtractor()
extractor.runInParallel(numProcesses=2, numThreads=4)
So...
It turns out the correct way to solve this is to implement a function to train the loop as such:
def run():
model = BertModel()
torch.multiprocessing.freeze_support()
print('loop')
train_loop(model, df_train, df_val)
if __name__ == '__main__':
run()
Redefining that train_loop line in the end. Issue solved. For more see this link: https://github.com/pytorch/pytorch/issues/5858

How to correctly use Distributed Data Parallel when customizing 'parameters' in the model ?

I have customized a parameter in my model:
self.params = list(self.backbone.parameters())
for head in self.headlist:
self.params += list(head.parameters())
When I wrap my model with DDP, an error occurs when defining the optimizer
optimizer = optim.SGD(model.params, lr=FLAGS.lr, momentum=FLAGS.momentum, weight_decay=FLAGS.weight_decay)
AttributeError 'DistributedDataParallel' object has no attribute 'params '
I think the error is probably caused by my customized "self.params"
Is the following code correct:
model = torch.nn.parallel.DistributedDataParallel(model,device_ids=local_rank)
model_without_ddp = model.module
**
optimizer = optim.SGD(model_without_ddp.params, lr=FLAGS.lr, momentum=FLAGS.momentum, weight_decay=FLAGS.weight_decay)
Or is there any simpler code?
###################################
The detailed definition of the network is as follows:
class multiheadModel():
def __init__(self, num_heads, device, model_name):
self.device = device
self.num_heads = num_heads # global+K
if model_name == 'fcn8s':
self.backbone = VGG16_FCN8s(num_classes=19, backbone=1, head=0).to(device)
self.headlist = [VGG16_FCN8s(num_classes=19, backbone=0, head=1).to(device) for i in range(num_heads)]
self.model = VGG16_FCN8s(num_classes=19).to(device)
for name, param in self.backbone.named_parameters():
if ('conv3' in name) or ('conv4' in name):
param.requires_grad = True
else:
param.requires_grad = False
elif model_name == 'deeplab':
self.backbone = Res_Deeplab(num_classes=19, backbone=1, head=0).to(device)
self.headlist = [Res_Deeplab(num_classes=19, backbone=0, head=1).to(device) for i in range(num_heads)]
self.model = Res_Deeplab(num_classes=19).to(device)
for name, param in self.backbone.named_parameters():
if 'layer3' in name:
param.requires_grad = True
else:
param.required_grad = False
else:
print('ERROR : wrong model name')
sys.exit()
self.params = list(self.backbone.parameters())
for head in self.headlist:
self.params += list(head.parameters())
self.loss_fn = None
#self.k2head = {0:2,1:1,2:0,3:0,4:0,5:4,6:4,7:5}
#self.k2head = {0:2,1:1,2:0,3:0,4:0,5:3,6:3,7:4}
self.k2head = {0:2,1:1,2:0,3:0,4:3,5:3,6:4}
# set train and eval mode
def train(self):
self.backbone.train()
for head in self.headlist:
head.train()
def eval(self):
self.backbone.eval()
for head in self.headlist:
head.eval()
def computePredLoss(self, rgb, lbl, k):
x = self.backbone(rgb)
head_id = list(range(self.num_heads))
head_id.remove(self.k2head[k])
input_size = rgb.size()[2:]
loss = 0
for i in head_id:
pred = self.headlist[i](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
loss += self.loss_fn(pred, lbl)
return pred, loss
def forward(self, input):
output = {}
if "label" in input:
self.train()
pred,loss = self.computePredLoss(input['rgb'], input['label'], input['k'])
output['pred'], output['loss']=pred, loss
else:
self.eval()
x = self.backbone(input['rgb'])
k = -1
if "k" in input:
k = self.k2head[input['k']]
pred = self.headlist[k](x)
input_size = input['rgb'].size()[2:]
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
output['pred'] = pred
return output
def validate(self, loader, k=-2):
self.eval()
if k!=-2:
val_metrics = StreamSegMetrics(19)
val_metrics.reset()
with torch.no_grad():
for i, (batch, rgb_batch) in enumerate(loader):
rgb_batch = rgb_batch.to(device=self.device, dtype=torch.float)
batch = batch.to(device=self.device, dtype=torch.int64)
input_size = rgb_batch.size()[2:]
x = self.backbone(rgb_batch)
pred = self.headlist[k](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
preds = pred.detach().max(dim=1)[1].cpu().numpy()
targets = batch.cpu().numpy()
val_metrics.update(targets, preds)
score = val_metrics.get_results()
else:
val_metrics = [StreamSegMetrics(19) for i in range(self.num_heads)]
for metric in val_metrics:
metric.reset()
with torch.no_grad():
for i, (batch, rgb_batch) in enumerate(loader):
rgb_batch = rgb_batch.to(device=self.device, dtype=torch.float)
batch = batch.to(device=self.device, dtype=torch.int64)
input_size = rgb_batch.size()[2:]
x = self.backbone(rgb_batch)
for k in range(self.num_heads):
pred = self.headlist[k](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
preds = pred.detach().max(dim=1)[1].cpu().numpy()
targets = batch.cpu().numpy()
val_metrics[k].update(targets, preds)
score = [val_metrics[k].get_results() for k in range(self.num_heads)]
return score
def getHeadPaths(self, model_path, iteration=-1):
head_paths = []
if '_iter' in model_path:
base_path = model_path.split('_iter')[0]
else:
base_path = model_path.split('.pth')[0]
if iteration==-1:
for i in range(self.num_heads-1):
head_paths.append(base_path+'_except_g'+chr(97+i)+'.pth')
head_paths.append(model_path)
else:
for i in range(self.num_heads-1):
head_paths.append(base_path+'_except_g'+chr(97+i)+'_iter'+str(iteration)+'.pth')
head_paths.append(base_path+'_iter'+str(iteration)+'.pth')
return head_paths
def save(self, model_path, iteration=-1):
self.model.load_state_dict(self.backbone.state_dict(), strict=False)
head_paths = self.getHeadPaths(model_path, iteration)
for i in range(self.num_heads):
self.model.load_state_dict(self.headlist[i].state_dict(), strict=False)
torch.save(self.model.state_dict(), head_paths[i])
def load(self, model_path):
iteration = -1
if '_iter' in model_path:
iteration = int(model_path.split('_iter')[1].split('.pth')[0])
self.model.load_state_dict(torch.load(model_path))
self.backbone.load_state_dict(self.model.state_dict(), strict=False)
head_paths = self.getHeadPaths(model_path, iteration)
existance = 1
for path in head_paths:
if os.path.isfile(path)==False:
existance = 0
if existance==1:
print('loading from multiheads')
for i in range(self.num_heads):
self.model.load_state_dict(torch.load(head_paths[i]))
self.headlist[i].load_state_dict(self.model.state_dict(), strict=False)
else:
print('loading from singlehead')
for i in range(self.num_heads):
self.model.load_state_dict(torch.load(head_paths[-1]))
self.headlist[i].load_state_dict(self.model.state_dict(), strict=False)
def __call__(self, input):
return self.forward(input)

Slow filtering of tableview - QSortFilterProxyModel - QAbstractTableModel

I'm working on an app which displays some member info in a table view. I have a filter function to search in the table:
![image of the ui file]
The content of the table loads really fast but the filtering is extremely slow.
Here is the code:
class PandasTableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super(PandasTableModel, self).__init__()
self._data = data
a=os.getcwd()
self.icons_folder = a + "/assets/icons/"
def data(self, index, role):
# value = self._data.iloc[index.row()][index.column()]
column_value = index.column()
if role == Qt.DisplayRole:
return self._data.iloc[index.row()][index.column()]
return str(value)
if role == Qt.DisplayRole:
if isinstance(value, datetime):
return value.strftime("%d-%m-%Y")
else:
return str(value)
if role == Qt.DecorationRole:
# if isinstance(value, datetime):
if column_value == 12 or column_value == 23 or column_value == 25:
return QtGui.QIcon(self.icons_folder + "calendar.png")
elif column_value == 14:
return QtGui.QIcon(self.icons_folder + "iphone-icon.png")
elif column_value == 13 or column_value == 15:
return QtGui.QIcon(self.icons_folder + "icon-phone.png")
elif column_value == 16:
return QtGui.QIcon(self.icons_folder + "email-icon.png")
def rowCount(self, index):
return self._data.shape[0]
def columnCount(self, index):
return self._data.shape[1]
def headerData(self, section, orientation, role):
# section is the index of the column/row.
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return str(self._data.columns[section])
if orientation == Qt.Vertical:
return str(self._data.index[section])
class MembersAdminWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MembersAdminWindow, self).__init__()
self.selectionModel = None
self.ui = loadUi("uidesign/members/members2.ui", self)
self.default_pic = str(os.getcwd()) + "/assets/clipart/muaythai.png"
def LoadMemberdata(self):
self.ui.lblMemberID.clear()
self.ui.txtNickName.clear()
self.ui.txtName.clear()
self.ui.txtFirstName.clear()
self.ui.txtStreet.clear()
self.ui.txtHouseNumber.clear()
self.ui.txtCity.clear()
self.ui.txtPostalCode.clear()
self.ui.txtCountry.clear()
self.ui.txtNationality.clear()
self.ui.txtLanguage.clear()
self.ui.txtGender.clear()
self.ui.txtBirthDate.clear()
self.ui.txtFixedNumber.clear()
self.ui.txtMobileNumber.clear()
self.ui.txtBusinessNumber.clear()
self.ui.txtEmail.clear()
self.ui.txtPassword.clear()
self.ui.scrbMemberLevel.setValue(0)
self.ui.txtSportsType.clear()
self.ui.txtStatusMember.clear()
self.ui.txtDoctor.clear()
self.ui.txtSubscriptionType.clear()
self.ui.txtMemberStart.clear()
self.ui.txtInsuranceStart.clear()
self.ui.txtMemberInfo.clear()
self.ui.txtSaldo.clear()
self.ui.txtSaldo.hide()
self.ui.lblSaldo.hide()
self.ui.lblMemberCard.setPixmap(QtGui.QPixmap(self.default_pic))
start = timeit.default_timer()
print('Start LoadMemberdata\n')
self.ui.tableMembers.setEnabled(True)
folder = os.getcwd()
master_file = str(folder) + "/modules/ssh/downloads/master.pkl"
Member_data = pd.read_pickle(master_file)
df = pd.DataFrame(Member_data)
df.fillna('',inplace=True)
aantal_gebruikers = df.shape[0]
print(aantal_gebruikers, 'gebruikers zijn ingelezen')
self.model = PandasTableModel(df)
self.proxy_model = QSortFilterProxyModel()
self.proxy_model.setSourceModel(self.model)
self.ui.inputFilter.setText("")
self.ui.inputFilter.textChanged.connect(self.SetFilteredView)
filter_result = self.proxy_model.rowCount()
self.ui.lblTotalMembers.setText("(" + str(filter_result) + " gebruikers)")
self.ui.cmdNewMember.setEnabled(True)
self.ui.cmdSaveMember.setEnabled(False)
self.ui.cmdCancel.setEnabled(False)
self.ui.cmdChangeMember.setEnabled(False)
self.ui.cmdTakeMemberPicture.setEnabled(False)
self.ui.cmdMemberFaceId.setEnabled(False)
self.ui.lblSaldo.setEnabled(False)
self.ui.txtSaldo.setEnabled(False)
self.ui.lblSaldo.hide()
self.ui.txtSaldo.hide()
self.ui.lblMemberCard.setPixmap(QtGui.QPixmap(self.default_pic))
self.ui.groupMembersData.setEnabled(False)
print('\nEnd LoadMemberdata')
end = timeit.default_timer()
print("Process Time: ", (end - start))
def SetFilteredView(self):
print("Start set_filter")
filter_text = self.ui.inputFilter.text()
rows = self.ui.tableMembers.model().rowCount()
for row in range(rows):
self.filter_row(row, filter_text)
# self.proxy_model.setFilterFixedString(filter_text)
# filter_result = self.proxy_model.rowCount()
self.ui.lblTotalMembers.setText("(" + str(rows) + " gebruikers)")
print("Stop set_filter")
def filter_row(self, row, pattern):
print("Start filter_row")
if not pattern:
self.ui.tableMembers.setRowHidden(row, False)
return
model = self.ui.tableMembers.model()
columns = model.columnCount()
stringlist = []
# collect text from all columns into single string for searching
for c in range(columns):
mdx = model.index(row, c)
if mdx.isValid():
val = str(mdx.data(role=QtCore.Qt.DisplayRole)).lower()
stringlist.append(val)
# search for string
patterns = filter(None, [x.lower() for x in pattern.split(' ')])
results = all(any(x in y for y in stringlist) for x in patterns)
if results:
self.ui.tableMembers.setRowHidden(row, False)
else:
self.ui.tableMembers.setRowHidden(row, True)
print("Stop filter_row")
i noticed when i type in the filter text field that the function 'filter_row' is called about 2000 times so i think i have to look for the solution here ;-)
Can anyone give a hand ?
Cheers John

Don't see images on my buttons if I create them with a loop

I'm trying to make a program in Python 3.3.0 to train with Tkinter, but when I try to put images on buttons which are created in a loop, I obtain a few buttons that don't work (I can't click on them and they don't have images), and the last one is working and with the image on it. Here there's the code:
elenco = [immagine1, immagine2, immagine3, immagine 4]
class secondWindow:
def __init__(self):
self.secondWindow = Tk()
self.secondWindow.geometry ('500x650+400+30')
class mainWindow:
def __init__(self):
self.mainWindow = Tk()
self.mainWindow.geometry ('1100x650+100+10')
self.mainWindow.title('MainWindow')
def Buttons(self, stringa):
i = 0
for _ in elenco:
if stringa in _.lower():
j = int(i/10)
self.IM = PIL.Image.open (_ + ".jpg")
self.II = PIL.ImageTk.PhotoImage (self.IM)
self.button = Button(text = _, compound = 'top', image = self.II, command = secondWindow).grid(row = j, column = i-j*10)
i += 1
def mainEnter (self):
testoEntry = StringVar()
self.mainEntry = Entry(self.mainWindow, textvariable = testoEntry).place (x = 900, y = 20)
def search ():
testoEntry2 = testoEntry.get()
if testoEntry2 == "":
pass
else:
testoEntry2 = testoEntry2.lower()
mainWindow.Buttons(self, testoEntry2)
self.button4Entry = Button (self.mainWindow, text = 'search', command = search).place (x = 1050, y = 17)
MW = mainWindow()
MW.mainEnter()
mainloop()
If I try to create buttons in a loop without images, they work:
def Buttons(self, stringa):
i = 0
for _ in elenco:
if stringa in _.lower():
j = int(i/10)
self.button = Button(text = _, command = secondWindow).grid(row = j, column = i-j*10)
i += 1
And if I try to create a button with an image but not in a loop, it works too:
im = PIL.Image.open("immagine1.jpg")
ge = PIL.ImageTk.PhotoImage (im)
butt = Button(text = 'immagine', compound = 'top', image = ge, command = secondWindow).grid(row = 0, column = 0)
Let's say you have images named "image-i.png", i=0,..,9.
When I execute the following code (with python 3.5) I obtain ten working buttons with image and text:
from tkinter import Tk, Button, PhotoImage
root = Tk()
images = []
buttons = []
for i in range(10):
im = PhotoImage(master=root, file="image-%i.png" % i)
b = Button(root, text="Button %i" % i, image=im, compound="left",
command=lambda x=i: print(x))
b.grid(row=i)
images.append(im)
buttons.append(b)
root.mainloop()

Python compiled code crashes

I made this game in python 2.7 and it worked in .py format but when I compiled it with py2exe it suddenly broke. It gave me this error:
"Microsoft Visuak C++ Runtime Library
Runtime Error!
Program C:\Python27\Helmetdodger\Stuffz\main.exe
This application has requested the Runtime to terminate it in an unusual way.
Please contact the program's support team."
The code:
import pygame
import random, sys, os
from pygame.locals import *
WINDOWWIDTH = 1200
WINDOWHEIGHT = 900
TEXTCOLOR = (255, 255, 255)
BACKGROUNDCOLOR = (0, 0, 0)
FPS = 40
BADDIEMINSIZE = 10
BADDIEMAXSIZE = 40
BADDIEMINSPEED = 1
BADDIEMAXSPEED = 8
ADDNEWBADDIERATE = 6
PLAYERMOVERATE = 5
def terminate():
pygame.quit()
os.exit(1)
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Helmetdodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.wav')
pygame.mixer.music.load('background.mid')
# set up images
playerImage1 = pygame.image.load('player1.png')
powerImage = pygame.image.load('power.png')
playerRect = playerImage1.get_rect()
baddieImage1 = pygame.image.load('baddie.png')
baddieImage2 = pygame.image.load('baddie1.png')
baddieImage3 = pygame.image.load('baddie2.png')
baddieImage4 = pygame.image.load('baddie3.png')
baddieImage5 = pygame.image.load('baddie4.png')
baddieImage6 = pygame.image.load('baddie5.png')
baddieImage7 = pygame.image.load('baddie6.png')
baddieImage8 = pygame.image.load('baddie7.png')
baddieImage9 = pygame.image.load('baddie8.png')
baddieImage10 = pygame.image.load('baddie9.png')
baddieImage11 = pygame.image.load('baddie10.png')
baddieImage12 = pygame.image.load('baddie11.png')
baddieImage13 = pygame.image.load('baddie12.png')
baddieImage14 = pygame.image.load('baddie13.png')
baddieImage15 = pygame.image.load('baddie14.png')
baddieImage16 = pygame.image.load('baddie15.png')
baddieImage17 = pygame.image.load('baddie16.png')
baddieImage18 = pygame.image.load('baddie17.png')
baddieImage19 = pygame.image.load('baddie18.png')
baddieImage20 = pygame.image.load('baddie19.png')
baddieImage21 = pygame.image.load('baddie20.png')
baddieImage22 = pygame.image.load('baddie21.png')
baddieImage23 = pygame.image.load('baddie22.png')
baddieImage24 = pygame.image.load('baddie23.png')
baddieImage25 = pygame.image.load('baddie24.png')
baddieImage26 = pygame.image.load('baddie25.png')
baddieImage27 = pygame.image.load('baddie26.png')
baddieImage28 = pygame.image.load('baddie27.png')
baddieImage29 = pygame.image.load('baddie28.png')
baddieImage30 = pygame.image.load('baddie29.png')
baddieImages = [baddieImage1, baddieImage2, baddieImage3, baddieImage4, baddieImage5, baddieImage6, baddieImage7, baddieImage8, baddieImage9, baddieImage10, baddieImage11, baddieImage12, baddieImage13, baddieImage14, baddieImage15, baddieImage16, baddieImage17, baddieImage18, baddieImage19, baddieImage20, baddieImage21, baddieImage22, baddieImage23, baddieImage24, baddieImage25, baddieImage26, baddieImage27, baddieImage28, baddieImage29, baddieImage20]
# show the "Start" screen
drawText('Helmetdodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
#Get highscore
topScore = 0
try:
file = open('hs.txt', "r")
topScore = file.read()
topScore = int(topScore)
file.close()
except:
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
pygame.mixer.music.play(-1, 0.0)
powerCount = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = True
if event.key == ord('x'):
slowCheat = True
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.type == MOUSEMOTION:
# If the mouse moves, move the player where the cursor is.
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieCount = random.randrange(len(baddieImages))
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImages[baddieCount], (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the mouse cursor to match the player.
pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
windowSurface.fill(BACKGROUNDCOLOR)
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage1, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
file = open("hs.txt", "w")
score = str(score)
file.write(score)
file.close()
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
pygame.mixer.music.stop()
gameOverSound.play()
drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
My buildscript was incorrect, I found a better buildscript online to use instead
try:
from distutils.core import setup
import py2exe, pygame
from modulefinder import Module
import glob, fnmatch
import sys, os, shutil
import operator
except ImportError, message:
raise SystemExit, "Unable to load module. %s" % message
#hack which fixes the pygame mixer and pygame font
origIsSystemDLL = py2exe.build_exe.isSystemDLL # save the orginal before we edit it
def isSystemDLL(pathname):
# checks if the freetype and ogg dll files are being included
if os.path.basename(pathname).lower() in ("libfreetype-6.dll", "libogg-0.dll","sdl_ttf.dll"): # "sdl_ttf.dll" added by arit.
return 0
return origIsSystemDLL(pathname) # return the orginal function
py2exe.build_exe.isSystemDLL = isSystemDLL # override the default function with this one
class pygame2exe(py2exe.build_exe.py2exe): #This hack make sure that pygame default font is copied: no need to modify code for specifying default font
def copy_extensions(self, extensions):
#Get pygame default font
pygamedir = os.path.split(pygame.base.__file__)[0]
pygame_default_font = os.path.join(pygamedir, pygame.font.get_default_font())
#Add font to list of extension to be copied
extensions.append(Module("pygame.font", pygame_default_font))
py2exe.build_exe.py2exe.copy_extensions(self, extensions)
class BuildExe:
def __init__(self):
#Name of starting + .py
self.script = "raw.py"
#Name of program
self.project_name = "main"
#Project url
self.project_url = "about:none"
#Version of program
self.project_version = "0.0"
#License of the program
self.license = "MyApps License"
#Auhor of program
self.author_name = "Me"
self.author_email = "example#example.com"
self.copyright = "Copyright (c) 2009 Me."
#Description
self.project_description = "MyApps Description"
#Icon file (None will use pygame default icon)
self.icon_file = None
#Extra files/dirs copied to game
self.extra_datas = []
#Extra/excludes python modules
self.extra_modules = []
self.exclude_modules = []
#DLL Excludes
self.exclude_dll = ['']
#python scripts (strings) to be included, seperated by a comma
self.extra_scripts = []
#Zip file name (None will bundle files in exe instead of zip file)
self.zipfile_name = None
#Dist directory
self.dist_dir ='C:\Python27\dist'
## Code from DistUtils tutorial at http://wiki.python.org/moin/Distutils/Tutorial
## Originally borrowed from wxPython's setup and config files
def opj(self, *args):
path = os.path.join(*args)
return os.path.normpath(path)
def find_data_files(self, srcdir, *wildcards, **kw):
# get a list of all files under the srcdir matching wildcards,
# returned in a format to be used for install_data
def walk_helper(arg, dirname, files):
if '.svn' in dirname:
return
names = []
lst, wildcards = arg
for wc in wildcards:
wc_name = self.opj(dirname, wc)
for f in files:
filename = self.opj(dirname, f)
if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename):
names.append(filename)
if names:
lst.append( (dirname, names ) )
file_list = []
recursive = kw.get('recursive', True)
if recursive:
os.path.walk(srcdir, walk_helper, (file_list, wildcards))
else:
walk_helper((file_list, wildcards),
srcdir,
[os.path.basename(f) for f in glob.glob(self.opj(srcdir, '*'))])
return file_list
def run(self):
if os.path.isdir(self.dist_dir): #Erase previous destination dir
shutil.rmtree(self.dist_dir)
#Use the default pygame icon, if none given
if self.icon_file == None:
path = os.path.split(pygame.__file__)[0]
self.icon_file = os.path.join(path, 'pygame.ico')
#List all data files to add
extra_datas = []
for data in self.extra_datas:
if os.path.isdir(data):
extra_datas.extend(self.find_data_files(data, '*'))
else:
extra_datas.append(('.', [data]))
setup(
cmdclass = {'py2exe': pygame2exe},
version = self.project_version,
description = self.project_description,
name = self.project_name,
url = self.project_url,
author = self.author_name,
author_email = self.author_email,
license = self.license,
# targets to build
windows = [{
'script': self.script,
'icon_resources': [(0, self.icon_file)],
'copyright': self.copyright
}],
options = {'py2exe': {'optimize': 2, 'bundle_files': 2, 'compressed': True, \
'excludes': self.exclude_modules, 'packages': self.extra_modules, \
'dll_excludes': self.exclude_dll,
'includes': self.extra_scripts} },
zipfile = self.zipfile_name,
data_files = extra_datas,
dist_dir = self.dist_dir
)
if os.path.isdir('build'): #Clean up build dir
shutil.rmtree('build')
if __name__ == '__main__':
if operator.lt(len(sys.argv), 2):
sys.argv.append('py2exe')
BuildExe().run() #Run generation
raw_input("Press any key to continue") #Pause to let user see that things ends

Resources