I am writing a chatroom using tkinter and socket. When I successfully login, I get a list of all the users on the server. Then I choose one item from the listbox1 and press Send Request. Here I temporarily set Send Request to run a function to print the item. However, no matter what item I choose, it always print ()
I have written self.listbox1.curselection. Maybe I'm missing something?
Please help me, thank you!
from Tkinter import *
import socket
########HelperFunction########
def chunkstring (block): #Use to make the block into chunks and count the sum of ASCII value of chunks
M = []
for i in range(0, 512, 32):
L = str((block[0 + i : 32 + i]))
sum = 0
for r in range(len(L)):
sum = sum + ord(L[r])
M.append(sum)
return M
def leftrotate(x, c):
return (x << c) & 0xFFFFFFFF | (x >> (32 - c) & 0x7FFFFFFF >> (32 - c))
########Connection########
def StartConnection (IPAddress, PortNumber): #Use to set up the connection between computers and servers
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IPAddress, PortNumber))
return s
def login (s, username, password): #Login Function
print username
print password
s.send('LOGIN ' + username + '\n')
data = s.recv(512)
List = data.split(" ") #send the commend and get something back
CH = List[2] # pick up the CHALLENGE code
CH = CH[:-2] # delete the last two unnecessary code
PD = password
message = PD + CH # combine password and CHALLENGE together
block = message + "1"
block = block + "0" * (512 - len(message) - 3 - 1) # add '0' to block and remain the space for last three digits
numLen = len(str(len(message)))
if numLen == 2: #If the password is very long, we should consider the last digits may be affected
block = block + "0" + str(len(message))
elif numLen == 3:
block = block + str(len(message))
M = chunkstring(block)
########## MD5
P = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
K = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391]
#Initialize variables
a0 = 0x67452301
b0 = 0xefcdab89
c0 = 0x98badcfe
d0 = 0x10325476
A = a0
B = b0
C = c0
D = d0
#Mainloop
for i in range(0, 64):
if i >= 0 and i <= 15:
F = (B & C) | ((~ B) & D)
F = F & 0xFFFFFFFF
g = i
elif i >= 16 and i <= 31:
F = (D & B) | ((~ D) & C)
F = F & 0xFFFFFFFF
g = (5 * i + 1) % 16
elif i >= 32 and i <= 47:
F = B ^ C ^ D
F = F & 0xFFFFFFFF
g = (3 * i + 5) % 16
elif i >= 48 and i <= 63:
F = C ^ (B | (~ D))
F = F & 0xFFFFFFFF
g = (7 * i) % 16
dTemp = D
D = C
C = B
B = B + leftrotate((A + F + K[i] + M[g]), P[i])
B = B & 0xFFFFFFFF
A = dTemp
#Add this chunk's hash to result so far:
a0 = (a0 + A) & 0xFFFFFFFF
b0 = (b0 + B) & 0xFFFFFFFF
c0 = (c0 + C) & 0xFFFFFFFF
d0 = (d0 + D) & 0xFFFFFFFF
result = str(a0) + str(b0) + str(c0) + str(d0)
s.send("LOGIN " + username + " " + result + "\n") #send messagedigest to server
reply = s.recv(512)
print reply
if "Successful" in reply:
openMainScreen()
return True
else:
First.quit()
return False
def getUsers(s):
s.send('#users')
data = s.recv(512)
data = data.split('#') # use "#" help to split the list
data = data[4:] # start from the 4th element in order to avoid the elements I don't need
return data
def getFriends(s):
s.send('#friends')
data = s.recv(512)
data = data.split('#')
data = data[4:]
return data
def getRequests(s):
s.send('#rxrqst')
data = s.recv(512)
data = data.split('#')
data = data[3:]
return data
########Interface#########
#--------Login--------#
class Login(Frame):
def __init__(self, master):
frame = Frame(master)
frame.pack()
First.geometry("250x250")
self.lab1 = Label(frame, text = "Username")
self.lab1.grid(row = 0, column = 125)
self.ent1 = Entry(frame)
self.ent1.grid(row = 1, column = 125)
self.lab2 = Label(frame, text = "Password")
self.lab2.grid(row = 2, column = 125)
self.ent2 = Entry(frame, show = "*")
self.ent2.grid(row = 3, column = 125)
self.button = Button(frame, text = "OK", command = self.Submit)
self.button.grid(row = 5, column = 125)
def Submit(self):
username = self.ent1.get()
password = self.ent2.get()
login(ss, username, password)
class MainScreen(Frame):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.lab1 = Label(frame, text = "All Users")
self.lab1.grid(row = 1, column = 100)
self.lab2 = Label(frame, text = "Your Friends")
self.lab2.grid(row = 1, column = 300)
self.lab3 = Label(frame, text = "Pending Requests")
self.lab3.grid(row = 1, column = 500)
self.button1 = Button(frame, text = "Send Request", command = self.Print)
self.button1.grid(row = 3, column = 100)
users = getUsers(ss)
self.listbox1 = Listbox(frame)
self.listbox1.grid(row = 2, column = 100)
for item in users:
self.listbox1.insert(END, item)
self.list1 = self.listbox1.curselection()
friends = getFriends(ss)
self.listbox2 = Listbox(frame)
self.listbox2.grid(row = 2, column = 300)
for item in friends:
self.listbox2.insert(END, item)
requests = getRequests(ss)
self.listbox3 = Listbox(frame)
self.listbox3.grid(row = 2, column = 500)
for item in requests:
self.listbox3.insert(END, item)
def Print(self):
print self.list1
def openMainScreen():
Second = Toplevel(First)
Second.title("Chat with Client")
Second.geometry("600x400")
mainscreen = MainScreen(Second)
First = Tk()
First.title("Login")
LoginScreen = Login(First)
ss = StartConnection("86.36.34.215", 15112)
First.mainloop()
First you have to click on any element on list.
And you have to use curselection() in Print()
def Print(self):
print self.listbox1.curselection()
Related
I am working on reproducing the result from a paper.
While running the seq_transformation.py I found this error.
How can I solve this problem?
Here is the code in seq_transformation.py
# Licensed under the MIT License.
import sys
sys.path.append(['../..'])
import os
import os.path as osp
import numpy as np
import pickle
import logging
import h5py
from sklearn.model_selection import train_test_split
from utils import create_aligned_dataset
root_path = './'
stat_path = osp.join(root_path, 'statistics')
setup_file = osp.join(stat_path, 'setup.txt')
camera_file = osp.join(stat_path, 'camera.txt')
performer_file = osp.join(stat_path, 'performer.txt')
replication_file = osp.join(stat_path, 'replication.txt')
label_file = osp.join(stat_path, 'label.txt')
skes_name_file = osp.join(stat_path, 'skes_available_name.txt')
denoised_path = osp.join(root_path, 'denoised_data')
raw_skes_joints_pkl = osp.join(denoised_path, 'raw_denoised_joints.pkl')
frames_file = osp.join(denoised_path, 'frames_cnt.txt')
save_path = './'
if not osp.exists(save_path):
os.mkdir(save_path)
def remove_nan_frames(ske_name, ske_joints, nan_logger):
num_frames = ske_joints.shape[0]
valid_frames = []
for f in range(num_frames):
if not np.any(np.isnan(ske_joints[f])):
valid_frames.append(f)
else:
nan_indices = np.where(np.isnan(ske_joints[f]))[0]
nan_logger.info('{}\t{:^5}\t{}'.format(ske_name, f + 1, nan_indices))
return ske_joints[valid_frames]
def seq_translation(skes_joints):
for idx, ske_joints in enumerate(skes_joints):
num_frames = ske_joints.shape[0]
num_bodies = 1 if ske_joints.shape[1] == 75 else 2
if num_bodies == 2:
missing_frames_1 = np.where(ske_joints[:, :75].sum(axis=1) == 0)[0]
missing_frames_2 = np.where(ske_joints[:, 75:].sum(axis=1) == 0)[0]
cnt1 = len(missing_frames_1)
cnt2 = len(missing_frames_2)
i = 0 # get the "real" first frame of actor1
while i < num_frames:
if np.any(ske_joints[i, :75] != 0):
break
i += 1
origin = np.copy(ske_joints[i, 3:6]) # new origin: joint-2
for f in range(num_frames):
if num_bodies == 1:
ske_joints[f] -= np.tile(origin, 25)
else: # for 2 actors
ske_joints[f] -= np.tile(origin, 50)
if (num_bodies == 2) and (cnt1 > 0):
ske_joints[missing_frames_1, :75] = np.zeros((cnt1, 75), dtype=np.float32)
if (num_bodies == 2) and (cnt2 > 0):
ske_joints[missing_frames_2, 75:] = np.zeros((cnt2, 75), dtype=np.float32)
skes_joints[idx] = ske_joints # Update
return skes_joints
def frame_translation(skes_joints, skes_name, frames_cnt):
nan_logger = logging.getLogger('nan_skes')
nan_logger.setLevel(logging.INFO)
nan_logger.addHandler(logging.FileHandler("./nan_frames.log"))
nan_logger.info('{}\t{}\t{}'.format('Skeleton', 'Frame', 'Joints'))
for idx, ske_joints in enumerate(skes_joints):
num_frames = ske_joints.shape[0]
# Calculate the distance between spine base (joint-1) and spine (joint-21)
j1 = ske_joints[:, 0:3]
j21 = ske_joints[:, 60:63]
dist = np.sqrt(((j1 - j21) ** 2).sum(axis=1))
for f in range(num_frames):
origin = ske_joints[f, 3:6] # new origin: middle of the spine (joint-2)
if (ske_joints[f, 75:] == 0).all():
ske_joints[f, :75] = (ske_joints[f, :75] - np.tile(origin, 25)) / \
dist[f] + np.tile(origin, 25)
else:
ske_joints[f] = (ske_joints[f] - np.tile(origin, 50)) / \
dist[f] + np.tile(origin, 50)
ske_name = skes_name[idx]
ske_joints = remove_nan_frames(ske_name, ske_joints, nan_logger)
frames_cnt[idx] = num_frames # update valid number of frames
skes_joints[idx] = ske_joints
return skes_joints, frames_cnt
def align_frames(skes_joints, frames_cnt):
"""
Align all sequences with the same frame length.
"""
num_skes = len(skes_joints)
max_num_frames = frames_cnt.max() # 300
aligned_skes_joints = np.zeros((num_skes, max_num_frames, 150), dtype=np.float32)
for idx, ske_joints in enumerate(skes_joints):
num_frames = ske_joints.shape[0]
num_bodies = 1 if ske_joints.shape[1] == 75 else 2
if num_bodies == 1:
aligned_skes_joints[idx, :num_frames] = np.hstack((ske_joints,
np.zeros_like(ske_joints)))
else:
aligned_skes_joints[idx, :num_frames] = ske_joints
return aligned_skes_joints
def one_hot_vector(labels):
num_skes = len(labels)
labels_vector = np.zeros((num_skes, 60))
for idx, l in enumerate(labels):
labels_vector[idx, l] = 1
return labels_vector
def split_train_val(train_indices, method='sklearn', ratio=0.05):
"""
Get validation set by splitting data randomly from training set with two methods.
In fact, I thought these two methods are equal as they got the same performance.
"""
if method == 'sklearn':
return train_test_split(train_indices, test_size=ratio, random_state=10000)
else:
np.random.seed(10000)
np.random.shuffle(train_indices)
val_num_skes = int(np.ceil(0.05 * len(train_indices)))
val_indices = train_indices[:val_num_skes]
train_indices = train_indices[val_num_skes:]
return train_indices, val_indices
def split_dataset(skes_joints, label, performer, camera, evaluation, save_path):
train_indices, test_indices = get_indices(performer, camera, evaluation)
m = 'sklearn' # 'sklearn' or 'numpy'
# Select validation set from training set
# train_indices, val_indices = split_train_val(train_indices, m)
# Save labels and num_frames for each sequence of each data set
train_labels = label[train_indices]
test_labels = label[test_indices]
train_x = skes_joints[train_indices]
train_y = one_hot_vector(train_labels)
test_x = skes_joints[test_indices]
test_y = one_hot_vector(test_labels)
save_name = 'NTU60_%s.npz' % evaluation
np.savez(save_name, x_train=train_x, y_train=train_y, x_test=test_x, y_test=test_y)
# Save data into a .h5 file
# h5file = h5py.File(osp.join(save_path, 'NTU_%s.h5' % (evaluation)), 'w')
# Training set
# h5file.create_dataset('x', data=skes_joints[train_indices])
# train_one_hot_labels = one_hot_vector(train_labels)
# h5file.create_dataset('y', data=train_one_hot_labels)
# Validation set
# h5file.create_dataset('valid_x', data=skes_joints[val_indices])
# val_one_hot_labels = one_hot_vector(val_labels)
# h5file.create_dataset('valid_y', data=val_one_hot_labels)
# Test set
# h5file.create_dataset('test_x', data=skes_joints[test_indices])
# test_one_hot_labels = one_hot_vector(test_labels)
# h5file.create_dataset('test_y', data=test_one_hot_labels)
# h5file.close()
def get_indices(performer, camera, evaluation='CS'):
test_indices = np.empty(0)
train_indices = np.empty(0)
if evaluation == 'CS': # Cross Subject (Subject IDs)
train_ids = [1, 2, 4, 5, 8, 9, 13, 14, 15, 16,
17, 18, 19, 25, 27, 28, 31, 34, 35, 38]
test_ids = [3, 6, 7, 10, 11, 12, 20, 21, 22, 23,
24, 26, 29, 30, 32, 33, 36, 37, 39, 40]
# Get indices of test data
for idx in test_ids:
temp = np.where(performer == idx)[0] # 0-based index
test_indices = np.hstack((test_indices, temp)).astype(np.int)
# Get indices of training data
for train_id in train_ids:
temp = np.where(performer == train_id)[0] # 0-based index
train_indices = np.hstack((train_indices, temp)).astype(np.int)
else: # Cross View (Camera IDs)
train_ids = [2, 3]
test_ids = 1
# Get indices of test data
temp = np.where(camera == test_ids)[0] # 0-based index
test_indices = np.hstack((test_indices, temp)).astype(np.int)
# Get indices of training data
for train_id in train_ids:
temp = np.where(camera == train_id)[0] # 0-based index
train_indices = np.hstack((train_indices, temp)).astype(np.int)
return train_indices, test_indices
if __name__ == '__main__':
camera = np.loadtxt(camera_file, dtype=np.int) # camera id: 1, 2, 3
performer = np.loadtxt(performer_file, dtype=np.int) # subject id: 1~40
label = np.loadtxt(label_file, dtype=np.int) - 1 # action label: 0~59
frames_cnt = np.loadtxt(frames_file, dtype=np.int) # frames_cnt
skes_name = np.loadtxt(skes_name_file, dtype=np.string_)
with open(raw_skes_joints_pkl, 'rb') as fr:
skes_joints = pickle.load(fr) # a list
skes_joints = seq_translation(skes_joints)
skes_joints = align_frames(skes_joints, frames_cnt) # aligned to the same frame length
evaluations = ['CS', 'CV']
for evaluation in evaluations:
split_dataset(skes_joints, label, performer, camera, evaluation, save_path)
create_aligned_dataset(file_list=['NTU60_CS.npz', 'NTU60_CV.npz'])
How can I solve this error to reproduce the result of the author?
The error is telling you that you have an axis of 1000 and you try reaching the 1000th element. This is perfectly logical, since Python is 0-indexed, that is, its indexes start from 0 and therefore the 1000th element has an index of 999.
The solution is to look at the stack trace, which tells you that in seq_transformation.py, line 246 you have an error. Look at that line and try to find out what's being indexed there and find out how a 1000 could be a value for the index of a 1000-sized entity.
these two functions are not working as args in the lamba function
which is calculating the price of the sweets
def mysweets():
b = v.get( ) # get the value of v set
cost=int(mysweets_price_list[b]) #price_display
print(cost)
def quantity_sweets():
q = int(spinbox1.get())
print(q)
price = lambda b, q : b * q # final price to be displayed in myLabel_3
print(price(b, q))
I have tried nested functions but they are not working, help please
anyone
from tkinter import *
myGui = Tk()
myGui.geometry('450x450+200+200')
myGui.title('Auto Sweet Dispenser')
price_display = ""
b = 0
#a = 0
q = 0
mysweets_price_list = {1 :9.00,
2 :7.50,
} # dict for the sweet prices
def mysweets():
b = v.get( ) # get the value of v set
cost=int(mysweets_price_list[b]) #price_display
print(cost)
def quantity_sweets():
q = int(spinbox1.get())
print(q)
price = lambda b, q : b * q # final price to be displayed in myLabel_3
print(price(b, q))
v =IntVar()
price =IntVar()
v.set(1)
myLabel = Label(myGui,text = 'Choose your sweets',font = 14, fg ='brown').place(x=140,y=55)#grid(row=3,column=10,sticky = 'e')
myRadio_1 = Radiobutton(myGui,text = 'Mints',variable = v, value = 1, command = mysweets).place(x= 160, y = 100)
myRadio_2 = Radiobutton(myGui,text = 'Nut log',variable = v, value = 2, command = mysweets).place(x= 160, y = 120)
myLabel_2 = Label(myGui,text = 'Select Quantity',font = 12, fg ='brown').place(x=160,y=160)#grid(row=3,column=10,sticky = 'e')
myLabel_3 = Label(myGui,textvariable = price ,font = "Times 14 bold",width = 14, fg ='white', bg= 'blue' ,relief = RAISED).place(x=160,y=220)#grid(row=3,column=10,sticky = 'e')
spinbox1 = Spinbox(myGui,from_=1,to = 6,command = quantity_sweets, state = NORMAL)
spinbox1.place(x=160,y=180)#
myGui.mainloop()
the code works except that price is not being displayed as the lambda
function is not working.
You don't need lambda here (in general lambda should be extremely rare). You only need a single function to get all the data, do the calculation, and update the Label. Like this:
from tkinter import *
myGui = Tk()
myGui.geometry('450x450+200+200')
myGui.title('Auto Sweet Dispenser')
mysweets_price_list = {1 :9.00,
2 :7.50,
} # dict for the sweet prices
def calculate():
b = v.get( ) # get the value of v set
cost=mysweets_price_list[b] #price
q = int(spinbox1.get()) # get quantity.
final_price = cost * q # final price to be displayed
price.set(final_price)
v =IntVar(value=1) # set initial value to 1
price = IntVar()
Label(myGui,text = 'Choose your sweets',font = 14, fg ='brown').place(x=140,y=55)#grid(row=3,column=10,sticky = 'e')
Radiobutton(myGui,text = 'Mints',variable = v, value = 1, command = calculate).place(x= 160, y = 100)
Radiobutton(myGui,text = 'Nut log',variable = v, value = 2, command = calculate).place(x= 160, y = 120)
Label(myGui,text = 'Select Quantity',font = 12, fg ='brown').place(x=160,y=160)#grid(row=3,column=10,sticky = 'e')
Label(myGui,textvariable = price ,font = "Times 14 bold",width = 14, fg ='white', bg= 'blue' ,relief = RAISED).place(x=160,y=220)#grid(row=3,column=10,sticky = 'e')
spinbox1 = Spinbox(myGui,from_=1,to = 6,command = calculate, state = NORMAL)
spinbox1.place(x=160,y=180)
calculate() # do the calculation at boot
myGui.mainloop()
Also, it's very important to know that if you do name = Widget().place() then the name is set to None and is useless. You need to do
name = Widget()
name.grid() # or pack() or place()
or
Widget().grid() # or pack() or place()
Don't mix those 2 styles! The 2-line style is much better, and what we usually use.
I'm building an app to 'roll' multiple die of the same face, so if I need to roll 5 8 sided die I select 5 in the QComboBox under the label D8, then 5 QLineEdit widgets pop up with the values of the 5 'die rolls' displayed.
Currently I'm able to display the correct number of QLineEdit widgets after a number in the QComboBox is selected. The problem comes when I try to remove the die roll displays entirely or set the number of QLineEdit widgets to less than the first value set. Sometimes it works, never when I try to set the displays to 0, other times I'll throw a KeyError or RuntimeError.
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QGridLayout, QPushButton, QLineEdit, QLabel, QComboBox, QDialog, QApplication
class RollMultiDiePopup(QDialog):
def __init__(self, parent=None):
super(RollMultiDiePopup, self).__init__(parent)
#self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Additional Dies to roll')
self.setContentsMargins(5, 5, 5, 5)
self.comboDict = {"D4": 4, "D6": 6, "D8": 8, "D10": 10, "D12": 12, "D20": 20}
self.comboLblDict = {"# of D4s": 0, "# of D6s": 0, "# of D8s": 0, "# of D10s": 0, "# of D12s": 0, "# of D20s": 0}
self.layoutGrid = QGridLayout(self)
self.layoutGrid.setSpacing(10)
self.gridRow = 0
self.gridCol = 0
self.comboLbl = {}
self.comboBoxes = {}
self.addnlInputs = {}
self.generatecombolabels()
self.generatecomboboxes()
self.generaterollbuttons()
self.setLayout(self.layoutGrid)
self.adjustSize()
def generatecombolabels(self):
self.gridCol = 0
for key, val in self.comboLblDict.items():
self.gridCol = self.gridCol + 1
self.comboLbl[key] = QLabel(key, self)
self.layoutGrid.addWidget(self.comboLbl[key], 0, self.gridCol)
def generatecomboboxes(self):
self.gridCol = 0
for key, val in self.comboDict.items():
self.gridCol = self.gridCol + 1
self.comboBoxes[key] = QComboBox(self)
self.comboBoxes[key].addItems([str(x) for x in range(21)])
#self.comboBoxes[key].activated.connect(self.adddisplays)
self.layoutGrid.addWidget(self.comboBoxes[key], 1, self.gridCol)
def generaterollbuttons(self):
self.gridCol = 0
for key, val in self.comboDict.items():
self.gridCol = self.gridCol + 1
buttons = QPushButton("Roll " + key + "s", self)
buttons.setToolTip("Roll D" + str(self.comboDict[key]) + " (1 - " + str(self.comboDict[key]) + ")")
#buttons.clicked.connect(partial(self.rolldie, val))
buttons.clicked.connect(self.adddisplays)
self.layoutGrid.addWidget(buttons, 2, self.gridCol)
def rolldie(self):
pass
def adddisplays(self):
d4s = int(self.comboBoxes["D4"].currentText())
d6s = int(self.comboBoxes["D6"].currentText())
d8s = int(self.comboBoxes["D8"].currentText())
d10s = int(self.comboBoxes["D10"].currentText())
d12s = int(self.comboBoxes["D12"].currentText())
d20s = int(self.comboBoxes["D20"].currentText())
dies = {1: d4s, 2: d6s, 3: d8s, 4: d10s, 5: d12s, 6: d20s}
#if d4s == 0 or d6s == 0 or d8s == 0 or d10s == 0 or d12s == 0 or d20s == 0:
self.removeaddeddisplays()
if d4s > 0 or d6s > 0 or d8s > 0 or d10s > 0 or d12s > 0 or d20s > 0:
for keys, vals in dies.items():
self.gridRow = 3
for i in range(vals):
self.gridRow += 1
self.addnlInputs["addnlInput" + str(i + 1)] = QLineEdit(self)
self.addnlInputs["addnlInput" + str(i + 1)].setAlignment(Qt.AlignRight)
self.addnlInputs["addnlInput" + str(i + 1)].setText("")
self.addnlInputs["addnlInput" + str(i + 1)].setPlaceholderText("Die Roll #" + str(i + 1))
self.layoutGrid.addWidget(self.addnlInputs["addnlInput" + str(i + 1)], self.gridRow, keys)
def removeaddeddisplays(self):
try:
for i in range(3, 21):
self.layoutGrid.removeWidget(self.addnlInputs["addnlInput" + str(i + 1)])
self.addnlInputs["addnlInput" + str(i + 1)].deleteLater()
self.addnlInputs["addnlInput" + str(i + 1)] = None
self.adjustSize()
except KeyError:
print("1")
except RuntimeError:
print("2")
if __name__ == "__main__":
app = QApplication()
w = RollMultiDiePopup()
w.show()
app.exec_()
This is the code to initially generate the QComboBoxes and populate the list of #s.
self.gridCol = 0
for key, val in self.comboDict.items():
self.gridCol = self.gridCol + 1
self.comboBoxes[key] = QComboBox(self)
self.comboBoxes[key].addItems([str(x) for x in range(21)])
#self.comboBoxes[key].activated.connect(self.adddisplays)
self.layoutGrid.addWidget(self.comboBoxes[key], 1, self.gridCol)
This is the code that adds the displays when the button that corresponds with the D# label/Combo box
d4s = int(self.comboBoxes["D4"].currentText())
d6s = int(self.comboBoxes["D6"].currentText())
d8s = int(self.comboBoxes["D8"].currentText())
d10s = int(self.comboBoxes["D10"].currentText())
d12s = int(self.comboBoxes["D12"].currentText())
d20s = int(self.comboBoxes["D20"].currentText())
dies = {1: d4s, 2: d6s, 3: d8s, 4: d10s, 5: d12s, 6: d20s}
#if d4s == 0 or d6s == 0 or d8s == 0 or d10s == 0 or d12s == 0 or d20s == 0:
self.removeaddeddisplays()
if d4s > 0 or d6s > 0 or d8s > 0 or d10s > 0 or d12s > 0 or d20s > 0:
for keys, vals in dies.items():
self.gridRow = 3
for i in range(vals):
self.gridRow += 1
self.addnlInputs["addnlInput" + str(i + 1)] = QLineEdit(self)
self.addnlInputs["addnlInput" + str(i + 1)].setAlignment(Qt.AlignRight)
self.addnlInputs["addnlInput" + str(i + 1)].setText("")
self.addnlInputs["addnlInput" + str(i + 1)].setPlaceholderText("Die Roll #" + str(i + 1))
self.layoutGrid.addWidget(self.addnlInputs["addnlInput" + str(i + 1)], self.gridRow, keys)
Here's the removeaddeddisplays function
try:
for i in range(3, 21):
self.layoutGrid.removeWidget(self.addnlInputs["addnlInput" + str(i + 1)])
self.addnlInputs["addnlInput" + str(i + 1)].deleteLater()
self.addnlInputs["addnlInput" + str(i + 1)] = None
self.adjustSize()
except KeyError:
print("1")
except RuntimeError:
print("2")
I've tried several different ways to remove the widgets and wound up with different results, only removing every other display, everything, every third..etc. This has been the most consistent way so far that I've found.
I'm using python 3 and pyside 2, I'll worry about handling the die rolls after I get the displays working properly.
If you want to remove a widget from a layout you just have to use deleteLater but that does not mean that the references will be deleted if they are stored in a list. In my strategy I eliminate all the QLineEdits with deleteLater, I reset the list that stored it and I create the new QLineEdits.
from PySide2 import QtCore, QtWidgets
class RollMultiDiePopup(QtWidgets.QDialog):
def __init__(self, parent=None):
super(RollMultiDiePopup, self).__init__(parent)
self._data = {
"D4": 4,
"D6": 6,
"D8": 8,
"D10": 10,
"D12": 12,
"D20": 20
}
self._lineedits = [[] for _ in self._data]
self._comboboxes = []
grid_layout = QtWidgets.QGridLayout(self)
self.create_labels()
self.create_comboboxes()
self.create_buttons()
def create_labels(self):
row = 0
grid_layout = self.layout()
for i, k in enumerate(self._data.keys()):
label = QtWidgets.QLabel("# of {}s".format(k))
grid_layout.addWidget(label, row, i)
def create_comboboxes(self):
row = 1
grid_layout = self.layout()
for i in range(len(self._data)):
combo = QtWidgets.QComboBox()
combo.addItems([str(j) for j in range(21)])
self._comboboxes.append(combo)
grid_layout.addWidget(combo, row, i)
def create_buttons(self):
row = 2
grid_layout = self.layout()
for i, (k, v) in enumerate(self._data.items()):
button = QtWidgets.QPushButton("Roll {}s".format(k))
button.setToolTip("Roll {}(1 - {})".format(k, v))
button.clicked.connect(self.update_lineedits)
grid_layout.addWidget(button, row, i)
#QtCore.Slot()
def update_lineedits(self):
row = 3
grid_layout = self.layout()
for r in self._lineedits:
for le in r:
le.deleteLater()
self._lineedits = [[] for _ in self._data]
for i, (les,combo) in enumerate(zip(self._lineedits, self._comboboxes)):
v = int(combo.currentText())
for j in range(v):
le = QtWidgets.QLineEdit()
le.setPlaceholderText("Die Roll #{}".format(j+1))
grid_layout.addWidget(le, row+j, i)
les.append(le)
QtCore.QTimer.singleShot(0, self.adjust_size)
#QtCore.Slot()
def adjust_size(self):
animation = QtCore.QPropertyAnimation(self, b"size", self)
animation.setStartValue(self.size())
animation.setEndValue(self.minimumSizeHint())
animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = RollMultiDiePopup()
w.show()
sys.exit(app.exec_())
For my coursework i am making a booking system and i have been messing around trying to make a page which shows current week lessons and when the button is clicked it comes up with that students details on a separate page.But i don't know how to go about passing that time into my open page sub(which writes a txt file which is going to be used for SQL to get the students details). The current way i have done it just passes the max times into the sub.
from tkinter import *
import datetime
class Application(Frame):
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
self.grid()
self.timetable_button_gen_weekdays()
self.timetable_button_gen_weekends()
def timetable_button_gen_weekdays(self):
c = datetime.datetime(100,1,1,16,00,00)
self.Monday_lbl = Label(self, text = "Monday")
self.Monday_lbl.grid(row = 1, column = 0)
self.Tuesday_lbl = Label(self, text = "Tuesday")
self.Tuesday_lbl.grid(row = 2, column = 0)
self.Wednesday_lbl = Label(self, text = "Wednesday")
self.Wednesday_lbl.grid(row = 3, column = 0)
self.Thursday_lbl = Label(self, text = "Thursday")
self.Thursday_lbl.grid(row = 4, column = 0)
self.Friday_lbl = Label(self, text = "Friday")
self.Friday_lbl.grid(row = 5, column = 0)
for k in range(8):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 0, column = k + 1)
for i in range(5):
for a in range(8):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 1, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def timetable_button_gen_weekends(self):
c = datetime.datetime(100,1,1,10,00,00)
self.Saturday_lbl = Label(self, text = "Saturday")
self.Saturday_lbl.grid(row = 8, column = 0)
self.Sunday_lbl = Label(self, text = "Sunday")
self.Sunday_lbl.grid(row = 9, column = 0)
self.weekend_lbl = Label(self, text = "Weekend")
self.weekend_lbl.grid(row = 6, column = 1, sticky = W)
for k in range(10):
b = c + datetime.timedelta(minutes = (30 * k))
d = b + datetime.timedelta(minutes = (30))
self.i_time_weekdays_lbl = Label(self, text = b.time().strftime('%H:%M')+" to "+d.time().strftime('%H:%M'))
self.i_time_weekdays_lbl.grid(row = 7, column = k + 1)
for i in range(2):
for a in range(10):
b = c + datetime.timedelta(minutes = (30 * a))
d = b + datetime.timedelta(minutes = (30))
bttn_i_a = Button(self, text = "available",command = lambda: self.OpenPage(b.time().strftime('%H:%M'),d.time().strftime('%H:%M')))
bttn_i_a.grid(row = i + 8, column = a + 1)
bttn_i_a.config(height = 2, width = 10)
def OpenPage(self,startime,finishtime):
file = open("PassTimes.txt","w")
file.write(startime)
file.write("\n")
file.write(finishtime)
print(startime)
print(finishtime)
filepath = "PresentStudent.py"
global_namespace = {"__file__": filepath, "__name__": "__main__"}
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), global_namespace)
root = Tk()
root.title("test")
root.geometry("2000x2000")
app = Application(root)
root.mainloop()
Welcome to SO.
General
IMHO, running the main routine of "PresentStudent.py" does not look that clean.
It works, but a main routine is built for when the script is called directly, not when it is imported and used in some other script.
Are you aware of the modules functionality in python?
I would recommend creating a function in PresentStudent.py that does what you are doing inside your main routine. Give the function parameters to pass the .txt-Filename.
e.g.
def presentStudentCall(inputFile):
and use it inside your script like:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# here we import PresentStudent.py, as we import it __main__ will not run
import PresentStudent
#[...]
def OpenPage(self, stime, etime):
#[...]
# Instead of executing a file we call the function from the module
PresentStudent.presentStudentCall(file)
If you want to display the data inside a second frame, you could also declare a class in PresentStudent.py and use it like:
def OpenPage(self, stime, etime):
#[...]
student=PresentStudent.Student() # assuming to name the class "Student"
student.presentStudentCall(file)
Your question itself
using the lambda does not need to be the best way. In matters of scope and garbage collecting your code only passes the last generated "b"s and "c"s to the definition.
What you could do to make it work is calculating the sender item in OpenPage:
To achieve that, I recommend having arrays for your time spans storing starting times.
Like
c = datetime.datetime(100,1,1,16,00,00)
self.weektimes = ["%s"%(c+datetime.timedelta(minutes=30*k)) for k in range(8)]
self.weekendtimes = ["%s"%((c+datetime.timedelta(minutes=30*k)) for k in range(10)]
First you need to bind the click event to the widget(in that case your button)
bttn_i_a.bind("<Button-1>", self.OnPage)
Your OpenPage could then look like this:
def OpenPage(self, event):
import time
# With that, we get the row and column where we clicked in
grid_info=event.widget.grid_info()
# week or weekend?
if grid_info["row"] > 5: #may depend on amount of headers
_timearray=self.weekendtimes
else:
_timearray=self.weektimes
# get the column
col=grid_info["column"]
# get the startTime
stime=_timearray[col]
# end time is +30 minutes
etime="%s"%(time.strptime("%s"%stime, "%H:%M")+time.struct_time(tm_min=30))
# now call the handler...
I am making a chatroom. In my code, I open a login window, and a user window. Then I choose the username from a listbox and then click Start Chat in classMainScreen
In my temporarily attempt, after click that button, it should create a child window with a tithe with username. That is, if I choose "A" "B" and "C" in the listbox2, it should open three windows with titles "A" "B" and "C"
However, I don't want to open two window with the same title. If I choose a username which has already used in the window title, it should just pull that window to the front.
I know there is a function can just check if a child window exists. But it can't detect the title of windows. These windows have the same instance(Do I describe it right?) but different titles in the function ChatScreen. So what should I do?
My code doesn't work exactly what I describe because I just make the temporarily code. I just want to know how to detect if the window is open by detecting the title first, then I can change my code.
Thanks for any help!
from Tkinter import *
import socket
########HelperFunction########
def chunkstring (block): #Use to make the block into chunks and count the sum of ASCII value of chunks
M = []
for i in range(0, 512, 32):
L = str((block[0 + i : 32 + i]))
sum = 0
for r in range(len(L)):
sum = sum + ord(L[r])
M.append(sum)
return M
def leftrotate(x, c):
return (x << c) & 0xFFFFFFFF | (x >> (32 - c) & 0x7FFFFFFF >> (32 - c))
########Connection########
def StartConnection (IPAddress, PortNumber): #Use to set up the connection between computers and servers
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IPAddress, PortNumber))
return s
def login (s, username, password): #Login Function
print username
print password
s.send('LOGIN ' + username + '\n')
data = s.recv(512)
List = data.split(" ") #send the commend and get something back
CH = List[2] # pick up the CHALLENGE code
CH = CH[:-2] # delete the last two unnecessary code
PD = password
message = PD + CH # combine password and CHALLENGE together
block = message + "1"
block = block + "0" * (512 - len(message) - 3 - 1) # add '0' to block and remain the space for last three digits
numLen = len(str(len(message)))
if numLen == 2: #If the password is very long, we should consider the last digits may be affected
block = block + "0" + str(len(message))
elif numLen == 3:
block = block + str(len(message))
M = chunkstring(block)
########## MD5
P = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
K = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391]
#Initialize variables
a0 = 0x67452301
b0 = 0xefcdab89
c0 = 0x98badcfe
d0 = 0x10325476
A = a0
B = b0
C = c0
D = d0
#Mainloop
for i in range(0, 64):
if i >= 0 and i <= 15:
F = (B & C) | ((~ B) & D)
F = F & 0xFFFFFFFF
g = i
elif i >= 16 and i <= 31:
F = (D & B) | ((~ D) & C)
F = F & 0xFFFFFFFF
g = (5 * i + 1) % 16
elif i >= 32 and i <= 47:
F = B ^ C ^ D
F = F & 0xFFFFFFFF
g = (3 * i + 5) % 16
elif i >= 48 and i <= 63:
F = C ^ (B | (~ D))
F = F & 0xFFFFFFFF
g = (7 * i) % 16
dTemp = D
D = C
C = B
B = B + leftrotate((A + F + K[i] + M[g]), P[i])
B = B & 0xFFFFFFFF
A = dTemp
#Add this chunk's hash to result so far:
a0 = (a0 + A) & 0xFFFFFFFF
b0 = (b0 + B) & 0xFFFFFFFF
c0 = (c0 + C) & 0xFFFFFFFF
d0 = (d0 + D) & 0xFFFFFFFF
result = str(a0) + str(b0) + str(c0) + str(d0)
s.send("LOGIN " + username + " " + result + "\n") #send messagedigest to server
reply = s.recv(512)
print reply
if "Successful" in reply:
openMainScreen()
return True
else:
First.quit()
return False
def getUsers(s):
s.send('#users')
data = s.recv(512)
data = data.split('#') # use "#" help to split the list
data = data[4:] # start from the 4th element in order to avoid the elements I don't need
return data
def getFriends(s):
s.send('#friends')
data = s.recv(512)
data = data.split('#')
data = data[4:]
return data
def getRequests(s):
s.send('#rxrqst')
data = s.recv(512)
data = data.split('#')
data = data[3:]
return data
def sendFriendRequest(s, friend):
num = len(str(friend)) # count the len of my friends' name
if 22 + num < 100: # if it is short, so I can add three 0s
size = '000' + str(22 + num)
elif 22 + num >= 100: # if it is long, I have to consider another situation
size = '00' + str(22 + num)
s.send('#' + size + '#request#friend#' + friend)
data = s.recv(512)
if "#ok" in data:
SendRequestDialog()
return True
else:
print False
return False
def acceptFriendRequest(s, friend):
num = len(str(friend)) # count the len of my friends' name
if 21 + num < 100: # if it is short, so I can add three 0s
size = '000' + str(21 + num)
elif 21 + num >= 100: # if it is long, I have to consider another situation
size = '00' + str(21 + num)
s.send('#' + size + '#accept#friend#' + friend)
data = s.recv(512)
if "#ok" in data:
Second.update()
return True
else:
return False
########Interface#########
#--------Login--------#
class Login(Frame):
def __init__(self, master):
frame = Frame(master)
frame.pack()
First.geometry("250x250")
self.lab1 = Label(frame, text = "Username")
self.lab1.grid(row = 0, column = 125)
self.ent1 = Entry(frame)
self.ent1.grid(row = 1, column = 125)
self.lab2 = Label(frame, text = "Password")
self.lab2.grid(row = 2, column = 125)
self.ent2 = Entry(frame, show = "*")
self.ent2.grid(row = 3, column = 125)
self.button = Button(frame, text = "OK", command = self.Submit)
self.button.grid(row = 5, column = 125)
def Submit(self):
username = self.ent1.get()
password = self.ent2.get()
login(ss, username, password)
class MainScreen(Frame):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.lab1 = Label(frame, text = "All Users")
self.lab1.grid(row = 1, column = 100)
self.lab2 = Label(frame, text = "Your Friends")
self.lab2.grid(row = 1, column = 300)
self.lab3 = Label(frame, text = "Pending Requests")
self.lab3.grid(row = 1, column = 500)
self.button1 = Button(frame, text = "Send Request", command = self.SendRequest)
self.button1.grid(row = 3, column = 100)
self.button2 = Button(frame, text = "Start Chat", command = ChatScreen)
self.button2.grid(row = 3, column = 300)
self.button3 = Button(frame, text = "Accept Request", command = self.AcceptRequest)
self.button3.grid(row = 3, column = 500)
users = getUsers(ss)
self.listbox1 = Listbox(frame)
self.listbox1.grid(row = 2, column = 100)
for item in users:
self.listbox1.insert(END, item)
self.value1 = str((self.listbox1.get(ACTIVE)))
friends = getFriends(ss)
self.listbox2 = Listbox(frame)
self.listbox2.grid(row = 2, column = 300)
for item in friends:
self.listbox2.insert(END, item)
requests = getRequests(ss)
self.listbox3 = Listbox(frame)
self.listbox3.grid(row = 2, column = 500)
for item in requests:
self.listbox3.insert(END, item)
def SendRequest(self):
friends = self.value1
sendFriendRequest(ss, friends)
def AcceptRequest(self):
Accept = str((self.listbox3.get(ACTIVE)))
num = self.listbox3.curselection()
num = int(num[0])
if acceptFriendRequest(ss, Accept) == True:
self.listbox2.insert(END, Accept)
self.listbox3.delete(num)
def StartChat(self):
global chatguy
chatguy = str((self.listbox2.get(ACTIVE)))
def ChatScreen():
aaa = Toplevel(First)
aaa.title("aaa1")
aaa.geometry("300x200")
def SendRequestDialog():
Third = Toplevel(First)
Third.title("Send Successfully")
Third.geometry("300x100")
lab = Label(Third, text = "The friend request was successfully sent")
lab.pack()
def openMainScreen():
global Second
Second = Toplevel(First)
Second.title("Chat with Client")
Second.geometry("600x400")
mainscreen = MainScreen(Second)
First = Tk()
First.title("Login")
LoginScreen = Login(First)
ss = StartConnection("86.36.34.215", 15112)
First.mainloop()
Since First is the parent of all your windows in the widget tree, you can check the children of First to detect already open windows. Something like this:
for key,val in First.children.iteritems():
if isinstance(val, tk.Toplevel):
print("window: " + val.title())
#or to get a list of all titles
titles = map(lambda win:win.title() , filter(lambda w : isinstance(w, tk.Toplevel), First.children.itervalues()))
if title not in titles:
#...