Skip to content

Commit

Permalink
add working PyQt5 dialog that adds to anki
Browse files Browse the repository at this point in the history
  • Loading branch information
seanlaidlaw committed May 22, 2020
0 parents commit d5ae69b
Show file tree
Hide file tree
Showing 2 changed files with 305 additions and 0 deletions.
128 changes: 128 additions & 0 deletions Anki-QuickAdd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import os
import signal
import sys
import urllib.request

from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QDesktopWidget
from PyQt5.QtWidgets import QLabel, QLineEdit


# Default AnkiConnect API functions
def request(action, **params):
return {"action": action, "params": params, "version": 6}


def invoke(action, **params):
requestJson = json.dumps(request(action, **params)).encode("utf-8")
response = json.load(
urllib.request.urlopen(
urllib.request.Request("http://localhost:8765", requestJson)
)
)
if len(response) != 2:
raise Exception("response has an unexpected number of fields")
if "error" not in response:
raise Exception("response is missing required error field")
if "result" not in response:
raise Exception("response is missing required result field")
if response["error"] is not None:
raise Exception(response["error"])
return response["result"]


# allow <Ctrl-c> from terminal to terminate the GUI
signal.signal(signal.SIGINT, signal.SIG_DFL)

# Interface XML files
current_file_path = __file__
current_file_dir = os.path.dirname(current_file_path)
GUIui = os.path.join(current_file_dir, "AnkiQuickAdd_layout.ui")

# Build graphical interface constructed in XML
gui_window_object, gui_base_object = uic.loadUiType(GUIui)


class QuickaddGuiClass(gui_base_object, gui_window_object):
"""
Class that constructs the PyQt graphical interface
"""

def __init__(self):
super(gui_base_object, self).__init__()
self.setupUi(self)
self.setWindowTitle("Anki QuickAdd")

# Center GUI on screen
qt_rectangle = self.frameGeometry()
center_point = QDesktopWidget().availableGeometry().center()
qt_rectangle.moveCenter(center_point)

# get information to populate dialog
deck_list = invoke("deckNames")
self.deck_comboBox.addItems(deck_list)
model_names = invoke("modelNames")
self.card_comboBox.addItems(model_names)

# load fields for default card
self.changed_card_comboBox()

# if selected chromosome changes, create new graph for variants by position for chosen chromosome
self.card_comboBox.currentTextChanged.connect(self.changed_card_comboBox)

# on pressing add button, add to anki
self.add_button.clicked.connect(self.add_fields_to_anki)

def empty_qt_layout(self, qt_layout_name):
while 1:
layout_widget = qt_layout_name.takeAt(0)
if not layout_widget:
break
layout_widget.widget().deleteLater()

def changed_card_comboBox(self):
self.empty_qt_layout(self.form_label_layout)

card = self.card_comboBox.currentText()
self.card_fields = invoke("modelFieldNames", modelName=card)
self.card_fields_inputs = []
for field in self.card_fields:
self.form_label_layout.addWidget(QLabel(field))
field_lineedit = QLineEdit()
self.form_label_layout.addWidget(field_lineedit)
self.card_fields_inputs.append(field_lineedit)

def add_fields_to_anki(self):
# create a dict of lineedits
i = 0
inputs_dict = {}
for inputs in self.card_fields_inputs:
inputs_dict[self.card_fields[i]] = inputs.text()
i = i + 1

# convert dict to json
add_json = {
"deckName": self.deck_comboBox.currentText(),
"modelName": self.card_comboBox.currentText(),
"fields": inputs_dict,
}

# submit json to Anki-Connect
invoke("addNote", note=add_json)

# close Anki QuickAdd on add
QuickaddApp.quit()


if __name__ == "__main__":
QuickaddApp = QApplication(sys.argv)
QuickaddGui = QuickaddGuiClass()

# show GUI
QuickaddGui.show()

# exit program on quitting the GUI
sys.exit(QuickaddApp.exec_())
177 changes: 177 additions & 0 deletions AnkiQuickAdd_layout.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>311</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Anki QuickAdd</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="widget_layout">
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="combobox_layout">
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="deck_combobox_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Deck:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="card_combobox_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Card</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="deck_comboBox"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="card_comboBox"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="form_label_layout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="select_a_deck_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; font-style:italic;&quot;&gt;Select a card to enter input in fields&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="textbox_1_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Card field 1</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="textbox_1_lineedit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="placeholderText">
<string>example input for field 1</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="textbox_2_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Card field 2</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="textbox_2_lineedit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="placeholderText">
<string>more example input for field 2</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="tags_layout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="tags_label">
<property name="text">
<string>Tags:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="add_button">
<property name="text">
<string>Add to Anki</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

0 comments on commit d5ae69b

Please sign in to comment.