568 lines
22 KiB
Python
568 lines
22 KiB
Python
|
|
#########################################################
|
|
## @file : kmanapp.py
|
|
## @desc : kindle note managerment tool GUI
|
|
## @create : 2020/06/03
|
|
## @author : Chengan
|
|
## @email : douboer@gmail.com
|
|
#########################################################
|
|
|
|
import sys
|
|
import os
|
|
from time import sleep
|
|
import pandas as pd
|
|
|
|
from PySide2.QtWidgets import *
|
|
|
|
from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject,
|
|
QAbstractTableModel, QObject, QPoint, QRect, QSize, QTime,
|
|
QUrl, Qt, QThread, Signal, QTimer)
|
|
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
|
|
QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter,
|
|
QPixmap, QRadialGradient, QStandardItem, QStandardItemModel)
|
|
|
|
from mainwindow import Ui_MainWindow
|
|
from kman import *
|
|
|
|
# import binary resource file(kmanapp_rc.py)
|
|
import kmanapp_rc
|
|
|
|
notes_temp = """<br><span style='font-size:22pt;color:maroon'>《{bookname}》</span>
|
|
<span style='font-size:22pt;color:maroon'> {author} </span>
|
|
<span style='font-size:22pt;color:maroon'> ({time}) </span>
|
|
<span style='font-size:11pt;color:maroon'> 【{note}】 </span><hr><br><br>
|
|
<span style='font-size:22pt;color:#31849B'>{content}</span>
|
|
<span style='font-size:11pt;color:maroon'>【P{position}】</span><br>"""
|
|
|
|
words_temp = """<br><span style='font-size:22pt;color:maroon'>{usage}</span><br><br>
|
|
<span style='font-size:12pt;color:maroon'> {bookname} </span>
|
|
<span style='font-size:12pt;color:maroon'> {author} </span>
|
|
<span style='font-size:12pt;color:maroon'> {category} </span>
|
|
<span style='font-size:12pt;color:maroon'> {timestamp} </span>
|
|
<span style='font-size:12pt;color:#31849B'>{position}</span><hr><br><br>"""
|
|
|
|
ONLY_TEST = 1
|
|
|
|
class kmanWindow(QMainWindow):
|
|
"""
|
|
def __init__(self, *args, **kwargs):
|
|
super(kmanWindow, self).__init__(*args, **kwargs)
|
|
"""
|
|
flag = True
|
|
def __init__(self, parent=None):
|
|
super(kmanWindow, self).__init__(parent)
|
|
|
|
# create ui and initial it
|
|
ui = Ui_MainWindow()
|
|
ui.setupUi(self)
|
|
self.ui = ui
|
|
|
|
self.add_ui_component()
|
|
|
|
# initial tree selected
|
|
self.tree_selected = 'note_root'
|
|
|
|
self.km = kMan()
|
|
# initial check order:
|
|
# 1. backup file bk.data ->
|
|
# 2. kindle(My Clippings.txt) ->
|
|
# 3. local file(config) ->
|
|
flg = 0
|
|
if os.path.exists(BACKUPNOTEFN) and os.path.exists(BACKUPWORDFN):
|
|
self.books_data = self.km.json2dict(BACKUPNOTEFN)
|
|
self.words_data = self.km.json2dict(BACKUPWORDFN)
|
|
if (len(self.books_data)*len(self.words_data[0]))>=1:
|
|
self.books_data = self.km.json2dict(BACKUPNOTEFN)
|
|
self.words_data = self.km.json2dict(BACKUPWORDFN)
|
|
flg = 1
|
|
|
|
if self.km.get_kindle_path() and (not flg):
|
|
self.import_kindle()
|
|
else:
|
|
self.books_data = self.km.import_clips()
|
|
self.words_data = self.km.import_words()
|
|
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data)
|
|
#self.filter_list = self.km.filter_words(self.words_data)
|
|
|
|
self.fill_treeview()
|
|
self.refresh_ui_component(comp=1)
|
|
|
|
# timer to check status of kindle
|
|
self.timer = QTimer(self)
|
|
self.timer.timeout.connect(self.show_status_info)
|
|
self.timer.start(1000)
|
|
|
|
# connect action/toolbutton to slot functions
|
|
ui.actionimportkindle.triggered.connect(lambda: self.import_kindle())
|
|
ui.actionimportlocal.triggered.connect(lambda: self.import_local())
|
|
ui.actionconfig.triggered.connect(lambda: self.config())
|
|
ui.actionwords.triggered.connect(lambda: self.words())
|
|
ui.actionstatistic.triggered.connect(lambda: self.statistic())
|
|
ui.actionhomepage.triggered.connect(lambda: self.homepage())
|
|
ui.actionabout.triggered.connect(lambda: self.about())
|
|
ui.actionflush.triggered.connect(lambda: self.refresh())
|
|
ui.actionexport.triggered.connect(lambda: self.export())
|
|
#ui.searchLineEdit.returnPressed.connect(self.search_return_press())
|
|
ui.searchComboBox.currentIndexChanged.connect(self.search_scope_change)
|
|
ui.searchToolButton.clicked.connect(self.search_button_clicked)
|
|
ui.treeView.clicked.connect(self.tree_item_clicked)
|
|
ui.tableView.clicked.connect(self.table_item_clicked)
|
|
ui.tableView.horizontalHeader().setStretchLastSection(True)
|
|
#ui.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
|
|
ui.tableView.verticalHeader().hide()
|
|
ui.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
ui.tableView.setColumnWidth(0, 40) # type
|
|
ui.tableView.setColumnWidth(2, 50) # author
|
|
ui.tableView.selectRow(0)
|
|
|
|
# initial tableView
|
|
data = self.convert_to_panda(self.filter_list)
|
|
ui.tablemodel = nTableModel(data)
|
|
ui.tableView.verticalHeader().hide()
|
|
ui.tableView.setModel(self.ui.tablemodel)
|
|
|
|
def add_ui_component(self):
|
|
self.ui.searchComboBox.addItems([u'ALL',u'BOOKNAME',u'CONTENT',u'AUTHOR'])
|
|
self.ui.treeView.resize(200,200)
|
|
|
|
# status bar
|
|
self.ui.status_label = QLabel()
|
|
self.ui.pe = QPalette()
|
|
|
|
def refresh_ui_component(self, comp=0):
|
|
""" refresh treeView, tableview, textedit information
|
|
after import or open clips file
|
|
Args: comp 0 - treeview + tablevew + textedit , initial, fill_treeview()
|
|
move to __init__()
|
|
1 - tablevew + textedit , note tree view clicked
|
|
2 - textedit , note table view clicked
|
|
3 - tablevew + textedit , word tree view clicked
|
|
4 - textedit , word table view clicked
|
|
"""
|
|
# refresh tableview click note tree
|
|
if comp in [1,2]:
|
|
data = self.convert_to_panda(self.filter_list,0)
|
|
# refresh tableview click word tree
|
|
elif comp in [3,4]:
|
|
data = self.convert_to_panda(self.filter_list,1)
|
|
|
|
# refresh tableview content
|
|
if hasattr(self.ui, 'tablemodel'):
|
|
del self.ui.tablemodel
|
|
self.ui.tablemodel = nTableModel(data)
|
|
self.ui.tableView.verticalHeader().hide()
|
|
self.ui.tableView.setModel(self.ui.tablemodel)
|
|
#self.ui.tablemodel.tabledata_update.connect(self.tabledata_update_slot)
|
|
|
|
# refresh textedit content
|
|
if comp in [1,2]:
|
|
if len(self.filter_list)>0:
|
|
[stype,sbookname,sauthor,sposition,stime,scontent] = self.filter_list[0]
|
|
self.ui.textEdit.setHtml(notes_temp.format(
|
|
bookname=sbookname, author=sauthor, time=stime,
|
|
note=stype, content=scontent, position=sposition))
|
|
elif comp in [3,4]:
|
|
self.render_textedit_words(self.words_data)
|
|
|
|
self.show_status_info()
|
|
|
|
def render_textedit_words(self, wdata, mrow=100):
|
|
[bookinfo, words, lookups] = wdata
|
|
|
|
index = self.ui.tableView.currentIndex()
|
|
if index.row() == -1:
|
|
word = self.filter_list[0][2]
|
|
else:
|
|
word = index.sibling(index.row(), 2).data()
|
|
|
|
txt = ""
|
|
for row in lookups:
|
|
if words[row[1]]['word'] == word:
|
|
[susage, stimestamp, sbookname, sauthor, scategory, sposition] = \
|
|
[row[4],row[5],bookinfo[row[2]]['bookname'], \
|
|
bookinfo[row[2]]['author'], words[row[1]]['category'],row[3]]
|
|
|
|
txt += words_temp.format(
|
|
usage=susage,bookname=sbookname,
|
|
author=sauthor,category=scategory,
|
|
timestamp=stimestamp,position=sposition)
|
|
|
|
self.ui.textEdit.setHtml(txt)
|
|
|
|
def convert_to_panda(self, mlist, tp=0):
|
|
if tp==0:
|
|
pdframe = pd.DataFrame(mlist, \
|
|
columns = ['Type','Bookname','Author','Position','Date','Content'])
|
|
else:
|
|
pdframe = pd.DataFrame(mlist, \
|
|
columns = ['Bookname','Author','Word','Category'])
|
|
return pdframe
|
|
|
|
def tabledata_update_slot(self, s):
|
|
print('call tabledata_update_slot() {}'.format(s))
|
|
|
|
def tree_item_clicked(self, modelidx):
|
|
model_index_list = self.ui.treeView.selectedIndexes() # QModelIndexList
|
|
model_index = model_index_list[0] # QModelIndex
|
|
itemmodel = model_index.model() #QAbstractItemModel/QStandardItemModel
|
|
item = itemmodel.itemFromIndex(modelidx) #QStandardItem
|
|
|
|
self.tree_selected = item.accessibleDescription()
|
|
print(self.tree_selected, item.text())
|
|
|
|
# filter clips
|
|
self.filter_list = None
|
|
info = re.split(r'\s+',item.text())[0]
|
|
comp = 0
|
|
if self.tree_selected in ['note_root', 'note_bookname', 'note_author']:
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data)
|
|
comp = 1
|
|
elif self.tree_selected in ['word_root', 'word_bookname']:
|
|
self.filter_list = self.km.filter_words(self.words_data)
|
|
comp = 3
|
|
elif self.tree_selected == 'note_bleaf': # bookname leaf
|
|
comp = 1
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data, info, 1)
|
|
elif self.tree_selected == 'note_aleaf': # author leaf
|
|
comp = 1
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data, info, 2)
|
|
elif self.tree_selected == 'word_leaf': # word bookname leaf
|
|
comp = 3
|
|
self.filter_list = self.km.filter_words(self.words_data, info)
|
|
else: return
|
|
|
|
if comp == 3:
|
|
self.ui.tableView.setColumnWidth(1, 50) # author
|
|
self.ui.tableView.setColumnWidth(3, 50) # category
|
|
# QHeaderView::Interactive 0
|
|
# QHeaderView::Stretch 1
|
|
# QHeaderView::Fixed 2
|
|
# QHeaderView::ResizeToContents 3
|
|
self.ui.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
|
|
if comp == 1:
|
|
self.ui.tableView.setColumnWidth(0, 40) # type
|
|
self.ui.tableView.setColumnWidth(2, 50) # author
|
|
self.ui.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
|
|
|
|
self.refresh_ui_component(comp)
|
|
|
|
def table_item_clicked(self, index):
|
|
"""
|
|
print('tableView.currentIndex().row() {} tableView.currentIndex().column() {}'
|
|
.format(self.ui.tableView.currentIndex().row(),
|
|
self.ui.tableView.currentIndex().column()))
|
|
"""
|
|
if not index.isValid(): return
|
|
|
|
if self.tree_selected.split('_')[0]=='note':
|
|
row = index.row()
|
|
stype = index.sibling(row, 0).data()
|
|
sbookname = index.sibling(row, 1).data()
|
|
sauthor = index.sibling(row, 2).data()
|
|
sposition = index.sibling(row, 3).data()
|
|
stime = index.sibling(row, 4).data()
|
|
scontent = index.sibling(row, 5).data()
|
|
|
|
self.ui.textEdit.setHtml(notes_temp.format(
|
|
bookname=sbookname, author=sauthor, time=stime,
|
|
note=stype, content=scontent, position=sposition))
|
|
else:
|
|
self.render_textedit_words(self.words_data)
|
|
|
|
def search_button_clicked(self):
|
|
search_word = self.ui.searchLineEdit.text()
|
|
if search_word.strip() == '':
|
|
self.messagebox(ico=2, info=u'\n\n search content is empty!')
|
|
return 0
|
|
content_type = self.ui.searchComboBox.currentText()
|
|
#content_idx = self.ui.searchComboBox.currentIndex()
|
|
[nu, sbks] = self.km.search_clip(self.books_data, search_word, 'ALL', content_type)
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(sbks)
|
|
self.refresh_ui_component(1)
|
|
|
|
print( 'call search_button_clicked()' )
|
|
|
|
def keyPressEvent(self, event):
|
|
#print('hasfocus {} key {} {} {}'.format(self.ui.searchLineEdit.hasFocus(),\
|
|
# event.key(), Qt.Key_Return, event.key()==Qt.Key_Return))
|
|
|
|
if (self.ui.searchLineEdit.hasFocus() and event.key() == Qt.Key_Return):
|
|
print('call keyPressEvent() {} '.format(event.key()))
|
|
self.search_button_clicked()
|
|
|
|
def search_return_press(self):
|
|
self.search_button_clicked()
|
|
|
|
print('call search_return_press()')
|
|
|
|
# XXX
|
|
def search_scope_change(self,t):
|
|
p = {0:'ALL',1:'TITLE',2:'AUTHOR',3:'CONTENT'}
|
|
s = self.ui.searchLineEdit.text()
|
|
#print(self.books_data)
|
|
#print(search_clip(self.books_data,s,'ALL',p[t]))
|
|
print('call search_scope_change()')
|
|
|
|
## XXX
|
|
'''
|
|
def check_kindle_status(self):
|
|
while self.flag:
|
|
self.show_status_info()
|
|
sleep(2)
|
|
'''
|
|
|
|
def show_status_info(self):
|
|
""" show status information on statusbar
|
|
Args:
|
|
conn: 1 if kindle is connected else 0
|
|
Return:
|
|
conn
|
|
"""
|
|
status = self.km.status_info()
|
|
self.ui.statusbar.showMessage(status[0],0)
|
|
self.ui.status_label.setText(status[1])
|
|
if not self.km.status:
|
|
self.ui.pe.setColor(QPalette.WindowText,Qt.red)
|
|
#self.ui.status_label.setAutoFillBackground(True)
|
|
self.ui.status_label.setPalette(pe)
|
|
self.ui.statusbar.addPermanentWidget(self.ui.status_label, stretch=0)
|
|
|
|
# define slot functions
|
|
def import_kindle(self):
|
|
fp = self.km.get_kindle_path()
|
|
if not fp:
|
|
self.messagebox(ico=2, info='\n\n kindle is not connected')
|
|
return 0
|
|
|
|
self.books_data = self.km.import_clips(fp+'documents/'+CLIPFN)
|
|
self.words_data = self.km.import_words(fp+'system/vocabulary/'+WORDFN)
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data)
|
|
self.filter_wordlist = self.km.filter_words(self.words_data)
|
|
|
|
self.fill_treeview()
|
|
self.refresh_ui_component(1)
|
|
|
|
def import_local(self):
|
|
fn, ft = QFileDialog.getOpenFileName(self,
|
|
"choose file to import",
|
|
'./', # start path
|
|
"All Files (*);;Text Files (*.txt)") # filter file type
|
|
self.fn = fn
|
|
|
|
self.books_data = self.km.import_clips(fn)
|
|
[self.filter_books, self.filter_list] = self.km.filter_clips(self.books_data)
|
|
|
|
self.fill_treeview()
|
|
self.refresh_ui_component(1)
|
|
|
|
#print('filename ', fn, 'filetype ', ft)
|
|
if fn == "": return False
|
|
|
|
def fill_treeview(self):
|
|
self.ui.model = QStandardItemModel()
|
|
|
|
rootItem = self.ui.model.invisibleRootItem()
|
|
item = QStandardItem('All Notes ({})'.format(self.km.get_totalnum_nt(self.books_data)))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/emblem_library.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
item.setIcon(icon)
|
|
item.setAccessibleDescription('note_root')
|
|
rootItem.appendRow(item)
|
|
parent_item = item
|
|
|
|
# add bookname tree
|
|
[numbooks, booknum] = self.km.get_bookname_num(self.books_data)
|
|
bookname_item = QStandardItem('Bookname ({})'.format(numbooks))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/book_open.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
bookname_item.setIcon(icon)
|
|
bookname_item.setAccessibleDescription('note_bookname')
|
|
parent_item.appendRow(bookname_item)
|
|
|
|
if numbooks > 0:
|
|
for k, v in booknum.items():
|
|
item = QStandardItem('{} ({})'.format(k, v))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/book_open_bookmark.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
item.setIcon(icon)
|
|
item.setAccessibleDescription('note_bleaf')
|
|
bookname_item.appendRow(item)
|
|
|
|
# add author tree
|
|
[numauthor, authnum] = self.km.get_author_num(self.books_data)
|
|
author_item = QStandardItem('Author ({})'.format(numauthor))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/person.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
author_item.setIcon(icon)
|
|
author_item.setAccessibleDescription('note_author')
|
|
parent_item.appendRow(author_item)
|
|
parent_item = author_item
|
|
|
|
if numauthor > 0:
|
|
for k, v in authnum.items():
|
|
item = QStandardItem('{} ({})'.format(k, v))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/user.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
item.setIcon(icon)
|
|
item.setAccessibleDescription('note_aleaf')
|
|
author_item.appendRow(item)
|
|
|
|
# add words root
|
|
word_rootItem = self.ui.model.invisibleRootItem()
|
|
[numwords, wordnum] = self.km.get_book_word_num(self.words_data)
|
|
item = QStandardItem('All Words({})'.format(numwords))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/emblem_library.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
item.setIcon(icon)
|
|
item.setAccessibleDescription('word_root')
|
|
word_rootItem.appendRow(item)
|
|
word_parent_item = item
|
|
|
|
# add word bookname tree
|
|
word_bookname_item = QStandardItem('Bookname ({})'.format(numbooks))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/book_open.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
word_bookname_item.setIcon(icon)
|
|
word_bookname_item.setAccessibleDescription('word_bookname')
|
|
word_parent_item.appendRow(word_bookname_item)
|
|
|
|
print( [numwords, wordnum] )
|
|
if numwords > 0:
|
|
for k, v in wordnum.items():
|
|
item = QStandardItem('{} ({})'.format(k, v))
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/book_open_bookmark.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
item.setIcon(icon)
|
|
item.setAccessibleDescription('word_leaf')
|
|
word_bookname_item.appendRow(item)
|
|
|
|
self.ui.treeView.setModel(self.ui.model)
|
|
self.ui.treeView.expandAll()
|
|
|
|
def config(self):
|
|
print("call slot config()")
|
|
pass
|
|
|
|
def words(self):
|
|
print("call slot words()")
|
|
pass
|
|
|
|
def statistic(self):
|
|
print("call slot statistic()")
|
|
pass
|
|
|
|
def homepage(self):
|
|
import webbrowser
|
|
webbrowser.open('https://gitee.com/douboer/kman')
|
|
|
|
print("call slot homepage()")
|
|
pass
|
|
|
|
def about(self):
|
|
self.messagebox(ico=1, info='\n'+ \
|
|
' kindle management tool \n\n' + \
|
|
' v1.0.4\n\n' + \
|
|
' Author: chengan\n\n' + \
|
|
' douboer@gmail.com')
|
|
|
|
print("call slot about()")
|
|
pass
|
|
|
|
def refresh(self):
|
|
self.import_kindle()
|
|
print("call slot refresh()")
|
|
pass
|
|
|
|
def export(self):
|
|
self.km.export_notes(self.filter_books, 'export', ft='MD')
|
|
print("call export()")
|
|
pass
|
|
|
|
def messagebox(self, ico=1, info=''):
|
|
""" unify messagebox
|
|
Args: ico - QMessageBox.NoIcon 0
|
|
QMessageBox.Information 1
|
|
QMessageBox.Warning 2
|
|
QMessageBox.Critical 3
|
|
QMessageBox.Question 4
|
|
"""
|
|
icons = {0:QMessageBox.NoIcon, \
|
|
1:QMessageBox.Information, \
|
|
2:QMessageBox.Warning, \
|
|
3:QMessageBox.Critical, \
|
|
4:QMessageBox.Question }
|
|
msgBox = QMessageBox()
|
|
msgBox.setText(info)
|
|
msgBox.setInformativeText("")
|
|
msgBox.setIcon(icons[ico])
|
|
msgBox.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
|
|
msgBox.setBaseSize(QSize(600, 300))
|
|
r = msgBox.exec()
|
|
|
|
# backup file when kman closed
|
|
# read backup file when kman start
|
|
def closeEvent(self, e):
|
|
with open(BACKUPNOTEFN, 'w', encoding='utf8', errors='ignore') as fw:
|
|
fw.write(self.km.dict2json(self.books_data))
|
|
with open(BACKUPWORDFN, 'w', encoding='utf8', errors='ignore') as fw:
|
|
fw.write(self.km.dict2json(self.words_data))
|
|
|
|
# stop check thread
|
|
self.flag = False
|
|
|
|
# thanks Martin Fitzpatrick ^_^
|
|
# https://www.learnpyqt.com/courses/model-views/qtableview-modelviews-numpy-pandas/
|
|
class nTableModel(QAbstractTableModel):
|
|
tabledata_update = Signal(str)
|
|
|
|
def __init__(self, data):
|
|
super(nTableModel, self).__init__()
|
|
self._data = data
|
|
|
|
def data(self, index, role):
|
|
if role == Qt.DisplayRole:
|
|
value = self._data.iloc[index.row(), index.column()]
|
|
self.tabledata_update[str].emit('{} {}'.format(index.row(),index.column()))
|
|
return str(value)
|
|
|
|
def rowCount(self, index):
|
|
return self._data.shape[0]
|
|
|
|
def columnCount(self, index):
|
|
return self._data.shape[1]
|
|
|
|
def headerData(self, section, orientation, role):
|
|
# section is the index of the column/row.
|
|
if role == Qt.DisplayRole:
|
|
if orientation == Qt.Horizontal:
|
|
return str(self._data.columns[section])
|
|
|
|
if orientation == Qt.Vertical:
|
|
return str(self._data.index[section])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
app = QApplication(sys.argv)
|
|
kmw = kmanWindow()
|
|
icon = QIcon()
|
|
icon.addFile(u":/icons/Cbb20.png", QSize(), QIcon.Normal, QIcon.Off)
|
|
kmw.setWindowIcon(icon)
|
|
kmw.setWindowTitle("kindle management")
|
|
kmw.resize(900, 600)
|
|
#kmw.showFullScreen()
|
|
kmw.show()
|
|
|
|
# loop check kindle is connected or not
|
|
# BUG to be implement XXXX
|
|
"""
|
|
try:
|
|
t = threading.Thread(target=kmw.check_kindle_status)
|
|
t.start()
|
|
except:
|
|
print ("Error: can not start thread")
|
|
"""
|
|
app.exec_()
|
|
|