TLDR:
I appended to the Editor window a progress bar that registers the amount of time I spent adding cards alongside with a widget that displays how many cards I added and the time (in minutes) it took to create them.
These widgets should be replaced with an updated version of themselves every time I add a card. However, what actually happens is that they get stacked instead. How to make it work properly?
I’ve managed to do a similar thing a few weeks ago, when I added a progress bar to the Main Window by adapting a trick I learned from the source code of the Card Info During Review addon. This “trick” works like this:
-
Create a function that removes all the widgets from the Main Window web;
-
Create a function that add these widgets back alongside with the progress bar widget;
-
Create a function that encompasses the first then the second function;
-
Use the
addHook
to fire the last function when certain things happen (e.g. profile loaded, question was showed, etc.)
I couldn’t reproduce this same trick with the Editor window, though.
Here’s a picture showing what I’ve described above:
Here’s the code¹:
import json
from anki import hooks, buildinfo
from anki.hooks import addHook
from aqt import editor, gui_hooks, mw
from aqt.utils import tooltip
from aqt.utils import *
from aqt.theme import theme_manager
from aqt.webview import AnkiWebView
from datetime import time, datetime
from PyQt5 import QtCore
class ProgressBar(object):
def __init__(self):
gui_hooks.editor_did_init.append(self.editor_init_hook)
def editor_init_hook(self, ed: editor.Editor):
# self.inject_pBar(ed)
gui_hooks.add_cards_did_init.append(lambda o: self.inject_pBar(ed))
# gui_hooks.add_cards_will_add_note.remove(lambda o: self._remove_pBar(ed))
gui_hooks.add_cards_did_add_note.append(lambda o: self.inject_pBar(ed))
# gui_hooks.editor_web_view_did_init.append(lambda o: self.inject_pBar(ed))
def inject_pBar(self, editor: editor.Editor):
lims = []
lims.append(
"id > %d" % ((mw.col.sched.day_cutoff - (1 * 1 * 86400)) * 1000)
)
lims.append("did in %s" % mw.col.sched._deck_limit())
lim = "where " + " and ".join(lims)
chunk = 1
a = mw.col.db.all(
"""
select
(cast((id/1000.0 - ?) / 86400.0 as int))/? as day,
(id)
from cards %s
group by day order by day"""
% lim,
mw.col.sched.day_cutoff,
chunk,
)
b = datetime.fromtimestamp(a[0][1] / 1000).strftime('%H:%M:%S')
c = mw.col.db.all(
"""
select
(cast((id/1000.0 - ?) / 86400.0 as int))/? as day,
count(id)
from cards %s
group by day order by day"""
% lim,
mw.col.sched.day_cutoff,
chunk,
)
d = c[0][1]
e = mw.col.db.all(
"""
select
(cast((id/1000.0 - ?) / 86400.0 as int))/? as day,
(id)
from cards %s
"""
% lim,
mw.col.sched.day_cutoff,
chunk,
)
f = datetime.fromtimestamp(e[-1][-1] / 1000).strftime('%H:%M:%S')
time1 = datetime.strptime(b, "%H:%M:%S")
time2 = datetime.strptime(f, "%H:%M:%S")
g = time2 - time1
gg = e[-1][-1] - a[0][1]
minutes=(gg/(1000*60))%60
minutes = int(minutes)
hours=(gg/(1000*60*60))%24
self.pbar = QProgressBar()
self.pbar.setTextVisible(False)
self.pbar.setUpdatesEnabled(True)
self.pbar.setMaximum(1000)
self.pbar.setMinimum(0)
self.pbar.setValue(round(hours * 60))
self.pbar.setStyleSheet('QProgressBar' '{ min-height: 2px; max-height: 2px; border-radius: 6px; text-align: center; font-size: 0px; background: #3a3a3a;}' 'QProgressBar::chunk {' +
'border-radius: 6px; background-color: #007ACC;}')
if self.pbar.value() == 0:
self.pbar.setStyleSheet('QProgressBar' '{ min-height: 2px; max-height: 2px; border-radius: 6px; text-align: center; font-size: 0px; background: #ffd700 /*#f1d710*/ /*#CC7A00*/;}' 'QProgressBar::chunk {' +
'border-radius: 6px; background-color: #f1d710 /*#CC7A00*/;}')
if round(hours * 60) == self.pbar.maximum():
self.pbar.setStyleSheet('QProgressBar' '{ min-height: 2px; max-height: 2px; border-radius: 6px; text-align: center; font-size: 0px; background: #3a3a3a;}' 'QProgressBar::chunk {' +
'border-radius: 6px; background-color: #00CC7A;}')
self.label = QLineEdit(str(d) + " cards | " + str(round(hours * 60)) + " min")
self.label.setMaximumHeight(35)
self.label.setMaximumWidth(110)
self.label.setReadOnly(True)
self.label.setAlignment(Qt.AlignCenter)
self.hlayout = QHBoxLayout()
self.hlayout.addWidget(self.label)
self.hlayout.addWidget(self.pbar)
self.qwidget = QWidget()
self.qwidget.setMaximumHeight(34)
self.qwidget.setLayout(self.hlayout)
layout = editor.outerLayout
layout.removeWidget(editor.web)
layout.addWidget(editor.web)
layout.addWidget(self.qwidget)
bar = ProgressBar()
1 - It’s adapted from the Editor Live Preview addon(https://ankiweb.net/shared/info/1960039667) (source code here).
EDIT: The code above only works if you’ve already added at least one card the current day. Also you’ve to move to the Overview screen (that screen Anki displays after you click on a deck name) before you open the Editor (Add Card) window.
These are issues I still have to figure out how to fix, but please let me know If you have the solution for them!