I am trying to create a list like in outlook. With list items with an layout like this:
Don't get me wrong this isn't a "give me the full answer" question. I just have the problem of the right naming. I would appreciate it a lot if some could throw in the right words and I will look for them by my own.
I used tkinter at the moment but in that it seems like there isn't a solution for that.
Kind regards.
I think Tkinter can do this by using a bit of object oriented programming you could define how one list element should look like and then with static variables you could define a position of a new line relative to the position of the previous line. Something like:
from tkinter import *
class Line:
y = 0 # static variable for the y position
def __init__(self):
self.y_local = Line.y
Line.y = Line.y + 40 # increase the static variable for the next line
print(self.y_local)
def draw(self, tk, h_line="Headline", a_info="Addtional Information", date="01/01/1970"):
self.label_head = Label(text=h_line)
self.label_head.place(x=20, y=self.y)
self.label_info = Label(text=a_info)
self.label_info.place(x=20, y=self.y+20)
self.label_date = Label(text='Date')
self.label_date.place(x=200, y=self.y)
self.label_ndate = Label(text=date)
self.label_ndate.place(x=200, y=self.y+20)
self.chkbtn = Checkbutton(tk, text="Checkbox")
self.chkbtn.place(x=300, y=self.y+20)
tk = Tk()
data = [
["News", "WWIII has been avoided", "02/04/2018"],
["Python", "Python solves 42 riddles", "02/04/2018"]
]
for line in data:
temp = Line()
temp.draw(tk, line[0], line[1], line[2])
mainloop()
Hope I understood your question well. That you have a list with information and want to display that in an easy and scalable way. I have not looked to add the lines around the information as I've never done that before I know there are separators I've used vertical once before but I wouldn't be surprised if you can draw a box around each line either.
Related
I got another little question...
I want to make multiple variables which I create with 'setattr'
That works quite fine. It creates these variables:
self.sectionButton_1 = Button(text=x)
self.sectionButton_2 = Button(text=x)
self.sectionButton_3 = Button(text=x)
Now I want them to get displayed on the window with tkinter so that this should happen:
self.sectionButton_1.grid(row=i, column=0)
self.sectionButton_2.grid(row=i, column=0)
and so on..
But how do I have to edit the loop that the sectionButtons gonna be created with .grid from tkinter in a loop without writing the above ten times.
# Display Section selection
def checkSection(self):
# Read all sections from config
self.sections = config.sections()
self.sectionsCount = str(len(self.sections))
self.i = 0
self.text = Label(text="Choose Section:" + self.sectionsCount)
self.text.grid(row=1, column=0)
for x in self.sections:
i = +1
setattr(self, 'sectionButton_' + str(i), Button(text=x))
I'm not that good at explaining but hopefully its enough to understand my problem ^^
If not, just comment, I will try to answer it
If you have a group of related variables of the same type and you're doing the same operations to each one then that's a natural place to switch to using a list instead of individual variables.
Your code would become more like:
self.sectionButtons = []
for i, x in enumerate(self.sections):
button = Button(text=x)
button.grid(row=i+1, column=0)
self.sectionButtons.append(button)
This also has the advantage of no longer needing to construct the variable names as strings and use setattr, which is often a sign there's a better way.
I was making an application using tkinter and came across an error. I wanted people to input a variable, which I have made, and then have that many Entry boxes popup on the screen for input. I was wondering what is wrong with my code, if it is possible, or if there is a better way. Thanks in advance!
p.s. the NoOfBoxes has been predefined
int(NoOfBoxes)
x = 1
while(NoOfBoxes>=x):
a = a + 50
fill_empty(a)
x = x + 1
def fill_empty():
empty = tk.Entry(self)
empty.grid(row=200,column=a)
return empty
In first line of shown code, you are converting NoOfBoxes to an integer but you are not assigning back it to NoOfBoxes hence, when while line comes, NoOfBoxes is still not an integer. Also, there is no parameter on your fill_empty definition.
Most likely you will need those Entry widgets at some point in your code, so it'll be much better if you keep references.
listOfEntries = [fill_empty(idx) for idx in range(int(NoOfBoxes))]
def fill_empty(a):
empty = tk.Entry(self)
empty.grid(row=200,column=a)
return empty
When you want to make any operation on those, you can easily do something like:
listOfEntries[0].get()
Thanks for looking into my question. I'll try to give you a big and small picture of what I'm trying to do here.
Big Picture:
So, basically I'm trying to make a simple mindmapping program where, after the first entry, every text I input unto the Entry widget is linked to the previous text via a line widget. So like this: Hello----There, and then Hello----There----Yo. Actually, I'm hoping for more modifications in the future like being able to rearrange the links via some metric I have yet explored, but this is basically it.
Small/Specific Picture:
I realize that in order to do this, I will have to find a way to acquire all the xy coordinates of every text drawn on the canvas (text I drew on the canvas by using the random function). I need the coordinates of the first text and the coordinates of the second text so I can use those to draw the line to visually link the two texts. I thought of using an array to list down all inputted text, but I realize that only stores the text and not the location of the text on the canvas. I have explored using tags, or using the coords functions or using the bbox function, but to no avail. Any clues on how to go about this? I would highly appreciate it, Thanks. :)
import Tkinter
import random
a = Tkinter.Tk()
b = Tkinter.Canvas(a, width=1000, height=500)
b.pack()
def c(event):
b.create_text(random.randint(50,940), random.randint(50,480), anchor="center", text=d.get())
f.append(d.get())
d.delete(0, 'end')
print f
#this function creates a randomly located text taken from the entry widget below and, at the same time, appends the text in the list known as f''
d = Tkinter.Entry(a)
d.pack()
d.bind("<Return>", c)
d.focus()
b.create_line(300, 250, 600, 290)
#this is my very early attempt at linking text inputted and drawn on the Canvas
f = []
a.mainloop()
Simply assign random values to variables before you use it to create text on canvas, and keep on list with object ID and text.
x = random.randint(...)
y = random.randint(...)
obj_id = b.create_text(x, y, ...)
f.append([x, y, obj_id, d.get()])
BTW: if you have obj_id then you can also do
x,y = b.coords(obj_id)
I've had this problem for a while where my quiz won't work, where certain tkinter windows wouldn't close even though the code was there. However, after speaking to my teacher, he said that it was possible to read my text file to get the questions and answers, then place them in a list so that I could randomly select them to be displayed in the window (That way no question appears twice). He then said that you could have the window refresh after each question is answered, putting a different question up with different answers (Maybe even a "Correct"/"Wrong" inbetween each question). If anyone has an idea how to do ths is would be a massive help. Thanks.
def quiz_easy():
global question
questions = []
correctanswers = []
possibleanswer1s = []
possibleanswer2s = []
possibleanswer3s = []
easy_questions = open("sup.txt", "r")
count = 1
for line in easy_questions:
if count == 1:
questions.append(line.rstrip())
elif count == 2:
correctanswers.append(line.rstrip())
elif count == 3:
possibleanswer1s.append(line.rstrip())
elif count == 4:
possibleanswer2s.append(line.rstrip())
elif count == 5:
possibleanswer3s.append(line.rstrip())
if count == 5:
count = 1
else:
count = count + 1
print(questions)
print (correctanswers)
randno1 = random.randint(0,len(questions)-1)
master = Tk()
text = Text(master)
text.insert(INSERT, questions[randno1])
text.insert(END, "?")
text.pack()
text.tag_add("here","5.0", "1.4")
text.tag_add("start", "1.8", "1.13")
Think OOP intead of sequencial
Your Quiz should be a class.
Avoiding MVC approach, stay simple the class directly handle the UI, the data and the process.
The constructor read the question file and update your internal data representation (That may be reworked too), and start the Root Tk instance
Create a method to display the question (a Label) and the area dedicated to the answer (an Entry)
Add a button "OK" or bind the key on the Entry widget to start a method dedicated to the control of the answer and displaying of the correct answer
Create this method
Add a method for the Tkinter mainloop
In the main of the script instanciate the quizz, call the method "display a question" and then call the method for mainloop()
We are waiting for your code ;-) to assist
tips: 1: Prefer:
import Tkinter as tk # instead of from Tkinter import * to keep your code explicit.
2: Forget the global directive in your code .. non sense here
3: the file reading is rought, the format of your file is not optimised.
to not going too quickly in XML paradygm ..
think about prefix ruler
QUE translate pig in french
COR cochon
ALT proc
ALT truie
ALT verrat
ALT porcelet
ALT cochonet
ALT gorret
ALT nourrin
ALT nourrain
ALT cochette
for each line you just append a possible answer in a list of possible answers
Ready to run your brain ... go. ^^
I'm writing a music player in python, with a cli using urwid. I intend to have the current playlist in a simpleListWalker, wrapped by a listbox, then columns, a pile, and finally a frame.
How do I replace the entire contents of this listbox (or simpleListWalker) with something else?
Relevant code:
class mainDisplay(object):
...
def renderList(self):
songList = db.getListOfSongs()
songDictList = [item for item in songList if item['location'] in
commandSh.currentPlaylists[commandSh.plyr.currentList]]
self.currentSongWidgets = self.createList(songDictList)
self.mainListContent = urwid.SimpleListWalker([urwid.AttrMap(w, None,
'reveal focus') for w in self.currentSongWidgets])
def initFace(self):#this is the init function that creates the interface
#on startup
...
self.scanPlaylists()
self.renderList()
self.mainList = urwid.ListBox(self.mainListContent)
self.columns = urwid.Columns([self.mainList, self.secondaryList])
self.pile = urwid.Pile([self.columns,
("fixed", 1, self.statusDisplayOne),
("fixed", 1, self.statusDisplayTwo),
("fixed", 1, self.cmdShInterface)], 3)
self.topFrame = urwid.Frame(self.pile)
Full code at: http://github.com/ripdog/PyPlayer/tree/cli - Check main.py for interface code.
The code is in a pretty bad state right now, and I've only been programming for two months. Any suggestions on code style, layout, or any other tips you may have are very much appreciated.
self.mainListContent[:] = [new, list, of, widgets]
should replace the whole list of widgets in place.
Next time post your question to the mailing list or the IRC channel if you want a faster response!