Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Software > Calibre > Development

Notices

Reply
 
Thread Tools Search this Thread
Old 12-14-2011, 06:20 PM   #1
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Working with DateTime custom columns programmatically?

I'm working on a new version of my Goodreads Sync plugin, and I need to do something I haven't done before of working with datetime custom columns.

1. Assume I get the Metadata object for a book, using mi = db.get_metadata(book_id, index_is_id=True). And lets say I know the custom column is called '#dateread'. When I query the value using this:

dateread = mi.get('#dateread')

I end up with this text value in my variable:
datetime.datetime(2011, 12, 14, 22, 50, 50, tzinfo=SafeLocalTimeZone())

So that presumes there has to be some sort of further manipulation of this to get it into an actual date time value. And presumably this may also need to take into account the format associated with the custom column?

Which leads on to the next question...

2. The point of retrieving this date, is to allow it to be edited as a cell within my QTableWidget. Is there either a cell widget I can reuse for editing dates or any other pointers on an alternative? Depending on whether there is, and what input it requires (a datetime object or a string) will perhaps help dictate the answer to question 1 in terms of what to retrieve the value of that custom column as.

Thanks...
kiwidude is offline   Reply With Quote
Old 12-14-2011, 10:05 PM   #2
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,915
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
1. get() should be returning an actual datetime object. Try printing type(dateread)

2. See the delegates in library/delegates.py (these are used in the main calibre book list to enable editing of published date)
kovidgoyal is offline   Reply With Quote
 
Enthusiast
Old 12-15-2011, 06:09 AM   #3
chaley
"chaley", not "charley"
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 5,422
Karma: 821648
Join Date: Jan 2010
Location: France
Device: Many android devices
The following program demonstrates that mi.get() returns a datetime object for a datetime custom column.

Code:
from calibre.ebooks.metadata.book.base import Metadata
from calibre.library.database2 import LibraryDatabase2
from calibre.utils.config import prefs

src = prefs['library_path']
db = LibraryDatabase2(src)

mi = db.get_metadata(1353, index_is_id=True)
dt = mi.get('#mydate')
print dt
print type(dt)
print dt.timetuple()
Output:
Code:
2011-11-23 09:01:10+01:00
<type 'datetime.datetime'>
time.struct_time(tm_year=2011, tm_mon=11, tm_mday=23, tm_hour=9, tm_min=1, tm_sec=10, tm_wday=2, tm_yday=327, tm_isdst=0)
Adding to kovid's suggestion, the delegate used for datetime custom columns is CcDateDelegate at line 246 of delegates.py. This delegate is used to both display and edit the value. The value itself comes from models.py, function data() (line 702) that calls datetime_type() (line 580).

Last edited by chaley; 12-15-2011 at 06:13 AM. Reason: Add delegate info
chaley is offline   Reply With Quote
Old 12-15-2011, 07:25 AM   #4
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,915
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
@charles: FYI, a nicer way to init the db object for the current library is

from calibre.library.db import db
db = db()
kovidgoyal is offline   Reply With Quote
Old 12-15-2011, 08:29 AM   #5
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Thanks Charles/Kovid,

I stupidly did not realise it actually was a datetime object I had - unfamiliar with what print() produces for python for this unfortunately. So that side of things is fine now, thanks.

I am looking into the delegates stuff. One thing that I have never properly got my head around, is the Qt way of doing models/views. I made an attempt with my Plugin Updater plugin, but in every other situation for my relatively simple plugin usage I have just found life to be an awful lot easier to directly populate the QTableWidget.

Which now possibly leaves me with a potential problem with trying to use CCDateDelegate (and I will want to use RatingDelegate as well) as I have no "model" of my own.

Am I correct in thinking I am going to have to create a model and do it that way to use those delegates?
kiwidude is offline   Reply With Quote
Old 12-15-2011, 08:35 AM   #6
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,915
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
You should be able to set a delegate on a qtablewidget (it is a subcalss of QTableView), though I have never tried it. And yeah, Qt model/view sucks.
kovidgoyal is offline   Reply With Quote
Old 12-15-2011, 08:44 AM   #7
chaley
"chaley", not "charley"
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 5,422
Karma: 821648
Join Date: Jan 2010
Location: France
Device: Many android devices
You can set an "QItemDelegate" for a QTableWidget. Unfortunately, the GUI delegates are subclasses of QStyledItemDelegate. Both QItemDelegate and QStyledItemDelegate inherit from QAbstractItemDelegate, and they both seem to have the same API.

First thing I would try is to set the delegate for the date column to an instance of CcDateDelegate using setItemDelegate, and then see what happens.

Making a model would imply also making a view. I don't see any way to get one's hands on the view in QTableWidget, and it is the view that sets the delegate.
chaley is offline   Reply With Quote
Old 12-15-2011, 09:05 AM   #8
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Ahhh, not just me who hates the Qt model/view then

I'll have an experiment to see what happens (to see if I can reuse QTableWidget). I guess what isn't obvious to me (in my utter ignorance) is where the delegate is going to get its value from. QTableWidget does still have a default "model", but you don't normally do anything with it, just setting cell widgets directly. So where would the model get the value from when asked by the delegate?
kiwidude is offline   Reply With Quote
Old 12-15-2011, 09:18 AM   #9
chaley
"chaley", not "charley"
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 5,422
Karma: 821648
Join Date: Jan 2010
Location: France
Device: Many android devices
IIRC, you don't set the widgets. Instead you provide an "item" for each cell. I think that the "setItem" call is speaking to the internal model & view. The view creates the widgets using default delegates.

The default view (built in to QTableWidget) will use the default delegate for a type. SetItemDelegateForColumn replaces that delegate with yours. The view will invoke the delegate passing the internal model. When it is time to dosplay something, something in the view will call the delegate's setEditorData(), which in turn will ask the supplied model for the data using model.data(). Alternatively, and if the delgate has the QTableWidget instance (and it can if passed to the constructor), it can get the data using tablewidget_instance.itemAt().

Have fun experimenting.
chaley is offline   Reply With Quote
Old 12-15-2011, 09:43 AM   #10
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Ahhh, think I might be getting somewhere. I have the rating delegate working anyway. This is what I did...
Code:
            delegate = RatingDelegate(self)
            self.setItemDelegateForColumn(self.rating_column_index, delegate)
...
            # Inside a loop adding rows to the QTableWidget
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, my_rating_value)
            self.setItem(row, self.rating_column_index, item)
However when I try exactly the same trick for the CcDateDelegate, I get this error:
Code:
Traceback (most recent call last):
  File "D:\CalibreDev\latest\calibre\src\calibre\gui2\library\delegates.py", line 267, in createEditor
AttributeError: 'QLineEdit' object has no attribute 'setDisplayFormat'
So maybe the default editor sitting behind QTableWidgetItem is a QLineEdit. Any guesses as to where I go with this? Do I need to do a setCellWidget instead of setItem, and use some other object instead?
kiwidude is offline   Reply With Quote
Old 12-15-2011, 10:01 AM   #11
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Ahhh, hang on - maybe if I convert the date into a QDate, then it will figure out the right widget for it...
kiwidude is offline   Reply With Quote
Old 12-15-2011, 10:37 AM   #12
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Ok, one step forward, two backwards it seems. I found that converting my python date into a QDateTime meant that QTableWidget creates the right sort of editor. However, the next error I get is this:

Traceback (most recent call last):
File "D:\CalibreDev\latest\calibre\src\calibre\gui2\lib rary\delegates.py", line 277, in setEditorData
AttributeError: 'QAbstractTableModel' object has no attribute 'db'

I thought I could fudge this by doing something like this when I populate the table:
self.model().db = self.db

But that ain't doing it for me either. Wondering if I should just write my own CCDateDelegate that takes a db in, so it doesn't have to try to get it from the model...

EDIT - that is definitely what I am going to do. Because I can now see the next problem will be how the editor tries to get its value, since the delegate does some mapping column lookups, none of which I want to have to replicate.

Still, the Calibre class gave me something I can copy/paste from - thanks guys

Last edited by kiwidude; 12-15-2011 at 10:44 AM.
kiwidude is offline   Reply With Quote
Old 12-15-2011, 10:45 AM   #13
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,915
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
You will not be able to use the Cc delegate directly, instead model your own delegate based on it.

Use index.data(Qt.DisplayRole) and index.data(Qt.EditRole) etc.

to get the data from the model of the QTableWidget in your delegate.
kovidgoyal is offline   Reply With Quote
Old 12-15-2011, 11:09 AM   #14
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,224
Karma: 1334002
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Yeah thx Kovid, that was the "doh" moment I realised once I got past the initial hurdles of figuring out whether I had to use a model or not. I've got it all working now, marvellous... thx to both of you for the help.
kiwidude is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Custom Columns - How are you using yours? nynaevelan Library Management 19 04-18-2011 12:42 AM
Converting text for a datetime custom column kiwidude Development 2 02-26-2011 10:47 AM
0.7.46 and custom columns meme Library Management 4 02-21-2011 04:21 AM
Managing Custom Columns ddjohn Library Management 3 02-19-2011 10:42 AM
Custom Columns - the Future? Starson17 Calibre 2 07-13-2010 09:56 AM


All times are GMT -4. The time now is 04:15 AM.


MobileRead.com is a privately owned, operated and funded community.