mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Fix usage of QApplication for PyQt 4.6, since in 4.6 the global application instance is garbage collected, we need to store it in a global variable
This commit is contained in:
parent
ef6e9a9abc
commit
a28079ff17
@ -87,4 +87,6 @@ class Economist(BasicNewsRecipe):
|
||||
feeds[key].append(article)
|
||||
|
||||
ans = [(key, feeds[key]) for key in ans if feeds.has_key(key)]
|
||||
if not ans:
|
||||
raise Exception('Could not find any articles. Has your subscription expired?')
|
||||
return ans
|
||||
|
@ -11,16 +11,15 @@ from PyQt4.Qt import QUrl, QApplication, QSize, QEventLoop, \
|
||||
SIGNAL, QPainter, QImage, QObject, Qt
|
||||
from PyQt4.QtWebKit import QWebPage
|
||||
|
||||
|
||||
class HTMLTableRenderer(QObject):
|
||||
|
||||
def __init__(self, html, base_dir, width, height, dpi, factor):
|
||||
'''
|
||||
`width, height`: page width and height in pixels
|
||||
`base_dir`: The directory in which the HTML file that contains the table resides
|
||||
`base_dir`: The directory in which the HTML file that contains the table resides
|
||||
'''
|
||||
QObject.__init__(self)
|
||||
|
||||
|
||||
self.app = None
|
||||
self.width, self.height, self.dpi = width, height, dpi
|
||||
self.base_dir = base_dir
|
||||
@ -30,10 +29,10 @@ class HTMLTableRenderer(QObject):
|
||||
self.page = QWebPage()
|
||||
self.connect(self.page, SIGNAL('loadFinished(bool)'), self.render_html)
|
||||
self.page.mainFrame().setTextSizeMultiplier(factor)
|
||||
self.page.mainFrame().setHtml(html,
|
||||
self.page.mainFrame().setHtml(html,
|
||||
QUrl('file:'+os.path.abspath(self.base_dir)))
|
||||
|
||||
|
||||
|
||||
|
||||
def render_html(self, ok):
|
||||
try:
|
||||
if not ok:
|
||||
@ -61,7 +60,7 @@ class HTMLTableRenderer(QObject):
|
||||
self.images.append((f, img.width(), img.height()))
|
||||
finally:
|
||||
QApplication.quit()
|
||||
|
||||
|
||||
def render_table(soup, table, css, base_dir, width, height, dpi, factor=1.0):
|
||||
head = ''
|
||||
for e in soup.findAll(['link', 'style']):
|
||||
@ -85,10 +84,11 @@ def render_table(soup, table, css, base_dir, width, height, dpi, factor=1.0):
|
||||
images, tdir = do_render(html, base_dir, width, height, dpi, factor)
|
||||
atexit.register(shutil.rmtree, tdir)
|
||||
return images
|
||||
|
||||
|
||||
def do_render(html, base_dir, width, height, dpi, factor):
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
if not is_ok_to_use_qt():
|
||||
raise Exception('Not OK to use Qt')
|
||||
tr = HTMLTableRenderer(html, base_dir, width, height, dpi, factor)
|
||||
tr.loop.exec_()
|
||||
return tr.images, tr.tdir
|
||||
return tr.images, tr.tdir
|
||||
|
@ -18,7 +18,6 @@ from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QImage
|
||||
from PyQt4.QtGui import QPainter
|
||||
from PyQt4.QtSvg import QSvgRenderer
|
||||
from PyQt4.QtGui import QApplication
|
||||
from calibre.ebooks.oeb.base import XHTML, XLINK
|
||||
from calibre.ebooks.oeb.base import SVG_MIME, PNG_MIME
|
||||
from calibre.ebooks.oeb.base import xml2str, xpath
|
||||
@ -30,8 +29,9 @@ KEEP_ATTRS = set(['class', 'style', 'width', 'height', 'align'])
|
||||
|
||||
class SVGRasterizer(object):
|
||||
def __init__(self):
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
if not is_ok_to_use_qt():
|
||||
raise Exception('Not OK to use Qt')
|
||||
|
||||
@classmethod
|
||||
def config(cls, cfg):
|
||||
|
@ -18,7 +18,7 @@ from calibre.ebooks.metadata import authors_to_string
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \
|
||||
QApplication, QPrinter, QMetaObject, QSizeF, Qt
|
||||
QPrinter, QMetaObject, QSizeF, Qt
|
||||
from PyQt4.QtWebKit import QWebView
|
||||
|
||||
from pyPdf import PdfFileWriter, PdfFileReader
|
||||
@ -37,8 +37,9 @@ class PDFMetadata(object):
|
||||
|
||||
class PDFWriter(QObject):
|
||||
def __init__(self, opts, log):
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
if not is_ok_to_use_qt():
|
||||
raise Exception('Not OK to use Qt')
|
||||
QObject.__init__(self)
|
||||
|
||||
self.logger = log
|
||||
|
@ -528,12 +528,14 @@ class Application(QApplication):
|
||||
if set_qt_translator(self._translator):
|
||||
self.installTranslator(self._translator)
|
||||
|
||||
_store_app = None
|
||||
|
||||
def is_ok_to_use_qt():
|
||||
global gui_thread
|
||||
global gui_thread, _store_app
|
||||
if islinux and ':' not in os.environ.get('DISPLAY', ''):
|
||||
return False
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
if _store_app is None and QApplication.instance() is None:
|
||||
_store_app = QApplication([])
|
||||
if gui_thread is None:
|
||||
gui_thread = QThread.currentThread()
|
||||
return gui_thread is QThread.currentThread()
|
||||
|
@ -98,7 +98,7 @@ class FontKeyChooser(QDialog, Ui_Dialog):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt4.Qt import QApplication
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
is_ok_to_use_qt()
|
||||
d = FontKeyChooser()
|
||||
d.exec_()
|
||||
|
@ -20,9 +20,9 @@ if pictureflow is not None:
|
||||
class EmptyImageList(pictureflow.FlowImages):
|
||||
def __init__(self):
|
||||
pictureflow.FlowImages.__init__(self)
|
||||
|
||||
|
||||
class FileSystemImages(pictureflow.FlowImages):
|
||||
|
||||
|
||||
def __init__(self, dirpath):
|
||||
pictureflow.FlowImages.__init__(self)
|
||||
self.images = []
|
||||
@ -33,58 +33,58 @@ if pictureflow is not None:
|
||||
if not img.isNull():
|
||||
self.images.append(img)
|
||||
self.captions.append(os.path.basename(f))
|
||||
|
||||
|
||||
def count(self):
|
||||
return len(self.images)
|
||||
|
||||
|
||||
def image(self, index):
|
||||
return self.images[index]
|
||||
|
||||
|
||||
def caption(self, index):
|
||||
return self.captions[index]
|
||||
|
||||
|
||||
def currentChanged(self, index):
|
||||
print 'current changed:', index
|
||||
|
||||
|
||||
class DatabaseImages(pictureflow.FlowImages):
|
||||
|
||||
|
||||
def __init__(self, model, buffer=20):
|
||||
pictureflow.FlowImages.__init__(self)
|
||||
self.model = model
|
||||
QObject.connect(self.model, SIGNAL('modelReset()'), self.reset)
|
||||
|
||||
|
||||
def count(self):
|
||||
return self.model.count()
|
||||
|
||||
|
||||
def caption(self, index):
|
||||
return self.model.title(index)
|
||||
|
||||
|
||||
def reset(self):
|
||||
self.emit(SIGNAL('dataChanged()'))
|
||||
|
||||
|
||||
def image(self, index):
|
||||
return self.model.cover(index)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CoverFlow(pictureflow.PictureFlow):
|
||||
|
||||
|
||||
def __init__(self, height=300, parent=None, text_height=25):
|
||||
pictureflow.PictureFlow.__init__(self, parent,
|
||||
pictureflow.PictureFlow.__init__(self, parent,
|
||||
config['cover_flow_queue_length']+1)
|
||||
self.setSlideSize(QSize(int(2/3. * height), height))
|
||||
self.setMinimumSize(QSize(int(2.35*0.67*height), (5/3.)*height+text_height))
|
||||
self.setFocusPolicy(Qt.WheelFocus)
|
||||
self.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
|
||||
|
||||
|
||||
def wheelEvent(self, ev):
|
||||
ev.accept()
|
||||
if ev.delta() < 0:
|
||||
self.showNext()
|
||||
elif ev.delta() > 0:
|
||||
self.showPrevious()
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
CoverFlow = None
|
||||
DatabaseImages = None
|
||||
@ -105,7 +105,7 @@ if __name__ == '__main__':
|
||||
cf.setImages(model)
|
||||
cf.connect(cf, SIGNAL('currentChanged(int)'), model.currentChanged)
|
||||
w.setCentralWidget(cf)
|
||||
|
||||
|
||||
w.show()
|
||||
cf.setFocus(Qt.OtherFocusReason)
|
||||
sys.exit(app.exec_())
|
||||
|
@ -9,7 +9,7 @@ Scheduler for automated recipe downloads
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from PyQt4.Qt import QDialog, QApplication, SIGNAL, Qt, QTime, QObject, QMenu, \
|
||||
from PyQt4.Qt import QDialog, SIGNAL, Qt, QTime, QObject, QMenu, \
|
||||
QAction, QIcon, QMutex, QTimer
|
||||
|
||||
from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog
|
||||
@ -306,7 +306,8 @@ class Scheduler(QObject):
|
||||
self.download(urn)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
is_ok_to_use_qt()
|
||||
from calibre.library.database2 import LibraryDatabase2
|
||||
d = SchedulerDialog(RecipeModel(LibraryDatabase2('/home/kovid/documents/library')))
|
||||
d.exec_()
|
||||
|
@ -314,8 +314,8 @@ class %(classname)s(%(base_class)s):
|
||||
self.source_code.setText('')
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt4.Qt import QApplication
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
is_ok_to_use_qt()
|
||||
from calibre.library.database2 import LibraryDatabase2
|
||||
from calibre.web.feeds.recipes.model import RecipeModel
|
||||
d=UserProfiles(None, RecipeModel(LibraryDatabase2('/home/kovid/documents/library')))
|
||||
|
@ -282,9 +282,10 @@ class StatusBar(QStatusBar):
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Used to create the animated status icon
|
||||
from PyQt4.Qt import QApplication, QPainter, QSvgRenderer, QColor
|
||||
from PyQt4.Qt import QPainter, QSvgRenderer, QColor
|
||||
from subprocess import check_call
|
||||
app = QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
is_ok_to_use_qt()
|
||||
|
||||
def create_pixmaps(path, size=16, delta=20):
|
||||
r = QSvgRenderer(path)
|
||||
|
@ -10,7 +10,7 @@ from BeautifulSoup import BeautifulSoup, Tag
|
||||
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, QApplication, Qt, \
|
||||
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, Qt, \
|
||||
QPrinter, QPrintPreviewDialog, QPrintDialog, QDialog, QMetaObject, Q_ARG
|
||||
from PyQt4.QtWebKit import QWebView
|
||||
|
||||
@ -18,8 +18,9 @@ PRINTCSS = 'body{width:100%;margin:0;padding:0;font-family:Arial;color:#000;back
|
||||
|
||||
class Printing(QObject):
|
||||
def __init__(self, spine, preview):
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
from calibre.gui2 import is_ok_to_use_qt
|
||||
if not is_ok_to_use_qt():
|
||||
raise Exception('Not OK to use Qt')
|
||||
QObject.__init__(self)
|
||||
self.loop = QEventLoop()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user