[3]: https://qiita.com/The-town/items/3bc23ea6eef140787ee2 # How to use [4]:https://stackoverflow.com/questions/5348454/is-it-possible-to-colour-a-specific-item-in-a-listbox-widget
This article is about Qiita Summer Festival 2020 "If you want to make △△ (app) now using only 〇〇 (language)" This section describes the ** extension ** of the ** TODO application (distributed) ** created as a theme.
[If you want to make a TODO application (distributed) now using only Python] The TODO application I wrote in 2 I tried to expand the function. I've enjoyed making it just for the Qiita Summer Festival, so I'm going to slowly expand it.
I am using ** Python3 (ver 3.7) **, and I have confirmed the operation on Windows 10.
The code is located on the following GitHub. Feel free to use it.
[Code] 1
The application is as follows.
The expanded functions are the following four.
Metadata is added after ** TODO name ** as ** deadline ** or ** category **.
If you want to display ** metadata **, write ** # metadata 1 metadata 2 ** on the first line of the ** TODO ** file.
todo.txt
#2020/7/12 Fix
details of todo
** Metadata ** itself is managed by ** config.ini **. ** [Meta_data] ** part. After the number (serial number), enter the ** key name ** that you want to display as ** metadata **.
With this configuration file, if you write it in the first line of ** # 2020/07/29 ** and ** TODO file **, you can go to the corresponding TODO in the ** TODO list **. ** Deadline: 2020/07/29 ** will be added.
If you don't need the first metadata, but want the second metadata, that is, you want to display only ** categories ** ** # [1 character of half-width space] Category name **. Since the half-width space character is used as the delimiter, Enter ** one half-width space ** for unnecessary metadata.
config.ini
[Dir_names]
django=F:\Document\800_IT self-learning\09_python\10_Django
kivy=F:\Document\800_IT self-learning\09_python\14_Kivy
qiita=F:\Document\800_IT self-learning\09_python\51_Qiita
[File_names]
todo=*todo*.txt
[Meta_data]
1=Deadline
2=category
You can sort by selecting the sorting method from the pull-down on the left and pressing the update button.
** importance ** is the importance and ** limit ** is the deadline.
** importance ** uses the ** importance ** used in ** Importance_color ** in the configuration file. I think that ** importance ** is basically easier to understand if it is ** romaji ** or ** number ** such as ** A, B, C **. You can do whatever you want here by changing the config file.
config.ini
[Dir_names]
django=F:\Document\800_IT self-learning\09_python\10_Django
kivy=F:\Document\800_IT self-learning\09_python\14_Kivy
qiita=F:\Document\800_IT self-learning\09_python\51_Qiita
[File_names]
todo=*todo*.txt
[Importance_color]
default=white
A=red
B=yellow
C=green
[Meta_data]
1=Deadline
2=category
This is a function to change the color of the TODO list based on the correspondence between ** importance ** and ** color ** described in the configuration file.
As explained above, you can set ** [Importance_color] ** in ** config.ini ** to make it any color you like.
The file path is described on the TODO details screen, and you can open the ** TODO file ** using the ** OS default program ** by double-clicking on it.
In my environment, **. Txt ** is supposed to be opened in Sakura Editor, so clicking the file path from the TODO details screen will open Sakura Editor.
Details are described in [Last Post Page] [3].
The updated configuration files are ** Importance_color ** and ** Meta_data **.
config.ini
[Dir_names]
#The name displayed in the pull-down=Absolute path of the folder containing the TODO file
#Example
qiita=F:\Document\800_IT self-learning\09_python\51_Qiita
[File_names]
#The file name you want to display in the TODO list. Wildcard(*)You can use.
#Example
#Files with the string todo at the beginning
todo=todo*
#Files with the extension py
python=*.py
[Importance_color]
#The color that corresponds to the string used in the file name to indicate importance
#default is the color used for files that do not contain a severity string.
#The color is specified by a character string such as red or blue.
default=white
A=red
B=yellow
C=green
[Meta_data]
#The position of the string in the file to be used as the metadata and the key name of the metadata
#Of the first line of the TODO file#Recognize anything that starts with as metadata.
# example: #2020/09/01 Deadline for adding functions:2020/09/01 Category:Functions will be added.
# #Category if function is added:A function will be added (the deadline is ignored because there is one single-byte space).
1=Deadline
2=category
This simply implemented the ** search_mata_data ** method in the ** Todo ** class to get a list of metadata returned. The list of metadata is displayed by ** listbox.insert **.
display.py
...
class TodoDisplay:
def display_todo(self):
...
for path in paths:
metadata_list = self.todo.search_meta_data(path)
insert_statement_list = [path.split("\\")[-1].split(".")[0]]
insert_statement_list.extend(metadata_list)
insert_statement = " ".join(insert_statement_list)
self.listbox.insert(todo_list_box_id, insert_statement)
...
...
todo.py
class Todo:
...
def search_meta_data(self, path):
linecache.clearcache()
first_line = linecache.getline(path, 1)
if "#" == first_line[0]:
metadata_list = first_line[1:].split(" ")[:len(self.rule_file["Meta_data"].keys())]
display_metadata_list = []
for i, metadata in enumerate(metadata_list):
if metadata != "":
display_metadata_list.append(":".join([self.rule_file["Meta_data"][str(i+1)], metadata]))
return display_metadata_list
else:
return [""]
...
Call the ** sort_todo ** method in the ** Todo ** class from the ** TodoDisplay ** class.
The character string selected by ** combbox (pull-down) ** is passed as an argument, and the function to be called is changed according to the character string passed by ** sort_todo **.
display.py
class TodoDisplay:
...
def display_todo(self):
...
if self.sort_combbox.get() == "":
pass
else:
paths = self.todo.sort_todo(paths, method=self.sort_combbox.get())
...
...
todo.py
class Todo:
...
def sort_todo(self, paths, method):
if method == "importance":
return self.sort_importance(paths)
elif method == "limit":
return self.sort_todo_limit(paths)
def sort_importance(self, paths):
path_dicts = []
for path in paths:
path_dict = {}
file_name = path.split("\\")[-1].split(".")[0]
result = self.judge_importance(file_name)
if result is None:
path_dict["importance"] = "z"
else:
path_dict["importance"] = result.group()[1]
path_dict["path"] = path
path_dicts.append(path_dict)
sorted_path_dicts = sorted(path_dicts, key=lambda x: x["importance"])
sorted_paths = [sorted_path_dict["path"] for sorted_path_dict in sorted_path_dicts]
return sorted_paths
def sort_todo_limit(self, paths):
path_dicts = []
for path in paths:
path_dict = {}
first_metadata = self.search_meta_data(path)[0]
if self.rule_file["Meta_data"]["1"] in first_metadata:
path_dict["metadata_todo_limit"] = first_metadata.split(":")[-1]
else:
path_dict["metadata_todo_limit"] = "9999/12/31"
path_dict["path"] = path
path_dicts.append(path_dict)
sorted_path_dicts = sorted(path_dicts, key=lambda x: x["metadata_todo_limit"])
sorted_paths = [sorted_path_dict["path"] for sorted_path_dict in sorted_path_dicts]
return sorted_paths
...
Pass the file path to the ** search_importance ** method of the ** Todo ** class and have it return the corresponding color. Then use ** listbox.itemconfig ** for coloring.
I referred to the link below for how to color each line of the list box.
[Is it possible to colour a specific item in a Listbox widget?][4]
display.py
class TodoDisplay:
...
def display_todo(self):
...
for path in paths:
...
importance_color = self.todo.search_importance(path.split("\\")[-1].split(".")[0])
self.listbox.itemconfig(todo_list_box_id, {'bg': importance_color})
...
...
...
By using ** text.tag_bind **, you can associate ** event ** with a text string. You can also open the ** path ** file with the default program set in ** OS ** by setting ** os.system ("start" + path) **.
gui_object.py
class Listbox(tk.Listbox):
...
def show_detail(self, event=None):
...
self.text = Text(self.master_of_detail_text)
self.text.tag_config('system_message', background="white", foreground="blue", underline=1)
self.text.tag_bind("system_message", "<Double-Button-1>", self.open_with_another_app)
self.text.insert(END, self.get_todo_list()[self.index(ACTIVE)], "system_message")
...
...
def open_with_another_app(self, event=None):
path = self.get_todo_list()[self.index(ACTIVE)]
os.system("start " + path)
Somehow, it's become fun to grow the application. It may be the same as raising a character in an RPG.
I hope to use it from now on and expand it further. It's time to make the UI solid.
Recommended Posts