Krita Source Code Documentation
Loading...
Searching...
No Matches
PyKrita::Python Class Reference

#include <utilities.h>

Public Member Functions

PyObject * functionCall (const char *functionName, const char *moduleName, PyObject *arguments)
 
bool functionCall (const char *functionName, const char *moduleName=PYKRITA_ENGINE)
 
PyObject * itemString (const char *item, const char *moduleName=PYKRITA_ENGINE)
 
PyObject * itemString (const char *item, PyObject *dict)
 
bool itemStringDel (const char *item, const char *moduleName=PYKRITA_ENGINE)
 
bool itemStringSet (const char *item, PyObject *value, const char *moduleName=PYKRITA_ENGINE)
 
QString lastTraceback (void) const
 
PyObject * moduleActions (const char *moduleName)
 
PyObject * moduleConfigPages (const char *moduleName)
 
PyObject * moduleDict (const char *moduleName=PYKRITA_ENGINE)
 
QString moduleHelp (const char *moduleName)
 
PyObject * moduleImport (const char *moduleName)
 
bool prependPythonPaths (const QString &path)
 
bool prependPythonPaths (const QStringList &paths)
 
bool prependStringToList (PyObject *list, const QString &value)
 Prepend a QString to a list as a Python unicode object.
 
 Python ()
 
void traceback (const QString &description)
 
 ~Python ()
 

Static Public Member Functions

static void ensureInitialized ()
 
static bool isUnicode (PyObject *string)
 Test if a Python object is compatible with a QString.
 
static bool libraryLoad ()
 
static void libraryUnload ()
 
static void maybeFinalize ()
 
static bool setPath (const QStringList &scriptPaths)
 
static PyObject * unicode (const QString &string)
 Convert a QString to a Python unicode object.
 
static QString unicode (PyObject *string)
 Convert a Python unicode object to a QString.
 

Static Public Attributes

static const char * PYKRITA_ENGINE = "pykrita"
 

Private Member Functions

PyObject * kritaHandler (const char *moduleName, const char *handler)
 
bool prependPythonPaths (const QString &, PyObject *)
 

Private Attributes

PyGILState_STATE m_state
 
QString m_traceback
 

Detailed Description

Instantiate this class on the stack to automatically get and release the GIL.

Also, making all the utility functions members of this class means that in many cases the compiler tells us where the class in needed. In the remaining cases (i.e. bare calls to the Python C API), inspection is used to needed to add the requisite Python() object. To prevent this object being optimised away in these cases due to lack of use, all instances have the form of an assignment, e.g.:

 Python py = Python()

This adds a little overhead, but this is a small price for consistency.

Definition at line 72 of file utilities.h.

Constructor & Destructor Documentation

◆ Python()

PyKrita::Python::Python ( )

Definition at line 123 of file utilities.cpp.

124{
125#if THREADED
126 m_state = PyGILState_Ensure();
127#endif
128}
PyGILState_STATE m_state
Definition utilities.h:224

References m_state.

◆ ~Python()

PyKrita::Python::~Python ( )

Definition at line 130 of file utilities.cpp.

131{
132#if THREADED
133 PyGILState_Release(m_state);
134#endif
135}

References m_state.

Member Function Documentation

◆ ensureInitialized()

void PyKrita::Python::ensureInitialized ( )
static

Make sure the Python interpreter is initialized. Ideally should be only called once.

Definition at line 429 of file utilities.cpp.

430{
431 if (Py_IsInitialized()) {
432 warnScript << "Python interpreter is already initialized, not initializing again";
433 } else {
434 dbgScript << "Initializing Python interpreter";
435 Py_InitializeEx(0);
436 if (!Py_IsInitialized()) {
437 errScript << "Could not initialize Python interpreter";
438 }
439#if THREADED
440 s_pythonThreadState = PyGILState_GetThisThreadState();
441 PyEval_ReleaseThread(s_pythonThreadState);
442#endif
443 }
444}
#define dbgScript
Definition kis_debug.h:56
#define warnScript
Definition kis_debug.h:98
#define errScript
Definition kis_debug.h:118

References dbgScript, errScript, and warnScript.

◆ functionCall() [1/2]

PyObject * PyKrita::Python::functionCall ( const char * functionName,
const char * moduleName,
PyObject * arguments )

Definition at line 155 of file utilities.cpp.

160{
161 if (!arguments) {
162 errScript << "Missing arguments for" << moduleName << functionName;
163 return 0;
164 }
165 PyObject* const func = itemString(functionName, moduleName);
166 if (!func) {
167 errScript << "Failed to resolve" << moduleName << functionName;
168 return 0;
169 }
170 if (!PyCallable_Check(func)) {
171 traceback(QString("Not callable %1.%2").arg(moduleName).arg(functionName));
172 return 0;
173 }
174 PyObject* const result = PyObject_CallObject(func, arguments);
175 Py_DECREF(arguments);
176 if (!result)
177 traceback(QString("No result from %1.%2").arg(moduleName).arg(functionName));
178
179 return result;
180}
void traceback(const QString &description)
PyObject * itemString(const char *item, const char *moduleName=PYKRITA_ENGINE)

References errScript, itemString(), and traceback().

◆ functionCall() [2/2]

bool PyKrita::Python::functionCall ( const char * functionName,
const char * moduleName = PYKRITA_ENGINE )

Call the named module's named entry point.

Definition at line 147 of file utilities.cpp.

148{
149 PyObject* const result = functionCall(functionName, moduleName, PyTuple_New(0));
150 if (result)
151 Py_DECREF(result);
152 return bool(result);
153}
bool functionCall(const char *functionName, const char *moduleName=PYKRITA_ENGINE)

References functionCall().

◆ isUnicode()

bool PyKrita::Python::isUnicode ( PyObject * string)
static

Test if a Python object is compatible with a QString.

Definition at line 606 of file utilities.cpp.

607{
608 return PyUnicode_Check(string);
609}

◆ itemString() [1/2]

PyObject * PyKrita::Python::itemString ( const char * item,
const char * moduleName = PYKRITA_ENGINE )

Get the item from the named module's dictionary.

Returns
0 or a borrowed reference to the item.

Definition at line 191 of file utilities.cpp.

192{
193 if (PyObject* const value = itemString(item, moduleDict(moduleName)))
194 return value;
195
196 errScript << "Could not get item string" << moduleName << item;
197 return 0;
198}
float value(const T *src, size_t ch)
PyObject * moduleDict(const char *moduleName=PYKRITA_ENGINE)

References errScript, itemString(), moduleDict(), and value().

◆ itemString() [2/2]

PyObject * PyKrita::Python::itemString ( const char * item,
PyObject * dict )

Get the item from the given dictionary.

Returns
0 or a borrowed reference to the item.

Definition at line 200 of file utilities.cpp.

201{
202 if (dict)
203 if (PyObject* const value = PyDict_GetItemString(dict, item))
204 return value;
205 traceback(QString("Could not get item string %1").arg(item));
206 return 0;
207}

References traceback(), and value().

◆ itemStringDel()

bool PyKrita::Python::itemStringDel ( const char * item,
const char * moduleName = PYKRITA_ENGINE )

Delete the item from the named module's dictionary.

Definition at line 182 of file utilities.cpp.

183{
184 PyObject* const dict = moduleDict(moduleName);
185 const bool result = dict && PyDict_DelItemString(dict, item);
186 if (!result)
187 traceback(QString("Could not delete item string %1.%2").arg(moduleName).arg(item));
188 return result;
189}

References moduleDict(), and traceback().

◆ itemStringSet()

bool PyKrita::Python::itemStringSet ( const char * item,
PyObject * value,
const char * moduleName = PYKRITA_ENGINE )

Set the item in the named module's dictionary.

Definition at line 209 of file utilities.cpp.

210{
211 PyObject* const dict = moduleDict(moduleName);
212 const bool result = dict && !PyDict_SetItemString(dict, item, value);
213 if (!result)
214 traceback(QString("Could not set item string %1.%2").arg(moduleName).arg(item));
215 return result;
216}

References moduleDict(), traceback(), and value().

◆ kritaHandler()

PyObject * PyKrita::Python::kritaHandler ( const char * moduleName,
const char * handler )
private

Run a handler function supplied by the krita module on another module.

Returns
0 or a new reference to the result.

Definition at line 218 of file utilities.cpp.

219{
220 if (PyObject* const module = moduleImport(moduleName))
221 return functionCall(handler, "krita", Py_BuildValue("(O)", module));
222 return 0;
223}
PyObject * moduleImport(const char *moduleName)

References functionCall(), and moduleImport().

◆ lastTraceback()

QString PyKrita::Python::lastTraceback ( void ) const

Store the last traceback we handled using traceback().

Definition at line 225 of file utilities.cpp.

226{
227 QString result;
228 result.swap(m_traceback);
229 return result;
230}
QString m_traceback
Definition utilities.h:225

References m_traceback.

◆ libraryLoad()

bool PyKrita::Python::libraryLoad ( )
static

Load the Python shared library. This does nothing on Windows.

Definition at line 232 of file utilities.cpp.

233{
234 // no-op on Windows
235#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
236 if (!s_pythonLibrary) {
237
238 QFileInfo fi(PYKRITA_PYTHON_LIBRARY);
239 // get the filename of the configured Python library, without the .so suffix
240 const QString libraryName = fi.completeBaseName();
241 // 1.0 is the SONAME of the shared Python library
242 s_pythonLibrary = new QLibrary(libraryName, "1.0");
243 s_pythonLibrary->setLoadHints(QLibrary::ExportExternalSymbolsHint);
244 if (!s_pythonLibrary->load()) {
245 dbgScript << QString("Could not load %1 -- Reason: %2").arg(s_pythonLibrary->fileName()).arg(s_pythonLibrary->errorString());
246 delete s_pythonLibrary;
247 s_pythonLibrary = 0;
248 return false;
249 }
250 dbgScript << QString("Loaded %1").arg(s_pythonLibrary->fileName());
251 }
252#endif
253 return true;
254}

References dbgScript.

◆ libraryUnload()

void PyKrita::Python::libraryUnload ( )
static

Unload the Python shared library. This does nothing on Windows.

Definition at line 458 of file utilities.cpp.

459{
460 // no-op on Windows
461#ifndef Q_OS_WIN
462 if (s_pythonLibrary) {
463 // Shut the interpreter down if it has been started.
464 if (s_pythonLibrary->isLoaded()) {
465 s_pythonLibrary->unload();
466 }
467 delete s_pythonLibrary;
468 s_pythonLibrary = 0;
469 }
470#endif
471}

◆ maybeFinalize()

void PyKrita::Python::maybeFinalize ( )
static

Finalize the Python interpreter. Not guaranteed to work.

Definition at line 446 of file utilities.cpp.

447{
448 if (!Py_IsInitialized()) {
449 warnScript << "Python interpreter not initialized, no need to finalize";
450 } else {
451#if THREADED
452 PyEval_AcquireThread(s_pythonThreadState);
453#endif
454 Py_Finalize();
455 }
456}

References warnScript.

◆ moduleActions()

PyObject * PyKrita::Python::moduleActions ( const char * moduleName)

Get the Actions defined by a module. The returned object is [ { function, ( text, icon, shortcut, menu ) }... ] for each module function decorated with action.

Returns
0 or a new reference to the result.

Definition at line 473 of file utilities.cpp.

474{
475 return kritaHandler(moduleName, "moduleGetActions");
476}
PyObject * kritaHandler(const char *moduleName, const char *handler)

References kritaHandler().

◆ moduleConfigPages()

PyObject * PyKrita::Python::moduleConfigPages ( const char * moduleName)

Get the ConfigPages defined by a module. The returned object is [ { function, callable, ( name, fullName, icon ) }... ] for each module function decorated with configPage.

Returns
0 or a new reference to the result.

Definition at line 478 of file utilities.cpp.

479{
480 return kritaHandler(moduleName, "moduleGetConfigPages");
481}

References kritaHandler().

◆ moduleDict()

PyObject * PyKrita::Python::moduleDict ( const char * moduleName = PYKRITA_ENGINE)

Get the named module's dictionary.

Returns
0 or a borrowed reference to the dictionary.

Definition at line 494 of file utilities.cpp.

495{
496 PyObject* const module = moduleImport(moduleName);
497 if (module)
498 if (PyObject* const dictionary = PyModule_GetDict(module))
499 return dictionary;
500
501 traceback(QString("Could not get dict %1").arg(moduleName));
502 return 0;
503}

References traceback().

◆ moduleHelp()

QString PyKrita::Python::moduleHelp ( const char * moduleName)

Get the help text defined by a module.

Definition at line 483 of file utilities.cpp.

484{
485 QString r;
486 PyObject* const result = kritaHandler(moduleName, "moduleGetHelp");
487 if (result) {
488 r = unicode(result);
489 Py_DECREF(result);
490 }
491 return r;
492}
static PyObject * unicode(const QString &string)
Convert a QString to a Python unicode object.

References kritaHandler(), and unicode().

◆ moduleImport()

PyObject * PyKrita::Python::moduleImport ( const char * moduleName)

Import the named module.

Returns
0 or a borrowed reference to the module.

Definition at line 505 of file utilities.cpp.

506{
507 PyObject* const module = PyImport_ImportModule(moduleName);
508 if (module)
509 return module;
510
511 traceback(QString("Could not import %1").arg(moduleName));
512 return 0;
513}

References traceback().

◆ prependPythonPaths() [1/3]

bool PyKrita::Python::prependPythonPaths ( const QString & path,
PyObject * sys_path )
private

Definition at line 638 of file utilities.cpp.

639{
640 Q_ASSERT("Dir entry expected to be valid" && sys_path);
641 return bool(prependStringToList(sys_path, path));
642}
bool prependStringToList(PyObject *list, const QString &value)
Prepend a QString to a list as a Python unicode object.

References prependStringToList().

◆ prependPythonPaths() [2/3]

bool PyKrita::Python::prependPythonPaths ( const QString & path)

Add a given path to to the front of PYTHONPATH

Parameters
pathA string (path) to be added
Returns
true on success, false otherwise.

Definition at line 611 of file utilities.cpp.

612{
613 PyObject* sys_path = itemString("path", "sys");
614 return bool(sys_path) && prependPythonPaths(path, sys_path);
615}
bool prependPythonPaths(const QString &path)

References itemString(), and prependPythonPaths().

◆ prependPythonPaths() [3/3]

bool PyKrita::Python::prependPythonPaths ( const QStringList & paths)

Add listed paths to to the front of PYTHONPATH

Parameters
pathsA string list (paths) to be added
Returns
true on success, false otherwise.
Todo
Heh, boosts' range adaptors would be good here!

Definition at line 617 of file utilities.cpp.

618{
619 PyObject* sys_path = itemString("path", "sys");
620 if (!sys_path)
621 return false;
622
624 QStringList reversed_paths;
625 std::reverse_copy(
626 paths.begin()
627 , paths.end()
628 , std::back_inserter(reversed_paths)
629 );
630
631 Q_FOREACH(const QString & path, reversed_paths)
632 if (!prependPythonPaths(path, sys_path))
633 return false;
634
635 return true;
636}

References itemString(), and prependPythonPaths().

◆ prependStringToList()

bool PyKrita::Python::prependStringToList ( PyObject * list,
const QString & value )

Prepend a QString to a list as a Python unicode object.

Definition at line 137 of file utilities.cpp.

138{
139 PyObject* const u = unicode(value);
140 bool result = !PyList_Insert(list, 0, u);
141 Py_DECREF(u);
142 if (!result)
143 traceback(QString("Failed to prepend %1").arg(value));
144 return result;
145}
qreal u

References traceback(), u, unicode(), and value().

◆ setPath()

bool PyKrita::Python::setPath ( const QStringList & scriptPaths)
static

Set the Python paths by calling Py_SetPath. This should be called before initialization to ensure the proper libraries get loaded.

Definition at line 291 of file utilities.cpp.

292{
293
294 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!Py_IsInitialized(), false);
295 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!isPythonPathSet, false);
296
297// qDebug() << ">>>>>>>>>>>" << qgetenv("APPDIR")
298// << KoResourcePaths::getApplicationRoot()
299// << (!qgetenv("APPDIR").isNull() && KoResourcePaths::getApplicationRoot().contains(qgetenv("APPDIR")));
300
301
302#if defined Q_OS_WIN
303 bool runningInBundle = false;
304#elif defined Q_OS_MAC
305 bool runningInBundle = KoResourcePaths::getApplicationRoot().toLower().contains("krita.app");
306#else
307 bool runningInBundle = (!qgetenv("APPDIR").isNull() &&
308 KoResourcePaths::getApplicationRoot().contains(qgetenv("APPDIR")));
309#endif
310 dbgScript << "Python::setPath. Script paths:" << scriptPaths << runningInBundle;
311
312#ifdef Q_OS_WIN
313 constexpr char pathSeparator = ';';
314#else
315 constexpr char pathSeparator = ':';
316#endif
317
318 QString originalPath;
319 // Start with the script paths
320 QStringList paths(scriptPaths);
321
322 // Append the Krita libraries path
323 QString pythonLibsPath = findKritaPythonLibsPath("krita-python-libs");
324 dbgScript << "pythonLibsPath (krita-python-libs)" << pythonLibsPath;
325 if (pythonLibsPath.isEmpty()) {
326 dbgScript << "Cannot find krita-python-libs";
327 return false;
328 }
329 dbgScript << "Found krita-python-libs at" << pythonLibsPath;
330 paths.append(pythonLibsPath);
331
332#ifndef Q_OS_WIN
333 // Append the sip libraries path
334 pythonLibsPath = findKritaPythonLibsPath("sip");
335 dbgScript << "pythonLibsPath (sip)" << pythonLibsPath;
336 if (!pythonLibsPath.isEmpty()) {
337 dbgScript << "Found sip at" << pythonLibsPath;
338 paths.append(pythonLibsPath);
339 }
340#endif
341
342#ifdef Q_OS_WIN
343 // Find embeddable Python at <root>/python
344 QDir pythonDir(KoResourcePaths::getApplicationRoot());
345 if (pythonDir.cd("python")) {
346 const QString pythonHome = pythonDir.absolutePath();
347 dbgScript << "Found bundled Python at" << pythonHome;
348 // The default paths for Windows embeddable Python is
349 // ./python[0-9][0-9]+.zip;./
350 // Ordinarily, Python would find its own bundle here.
351 // But because we set sys.path manually afterwards,
352 // the prefix gets zeroed out. See
353 // https://docs.python.org/3/c-api/init.html#c.Py_SetPath
354 paths.append(pythonDir.absoluteFilePath(QStringLiteral("python%1%2.zip")
355 .arg(PY_MAJOR_VERSION)
356 .arg(PY_MINOR_VERSION)));
357 paths.append(pythonDir.absolutePath());
358 } else {
359 errScript << "Bundled Python not found, cannot set Python library paths";
360 return false;
361 }
362
363 // Add stock Python libs folder at <root>/lib/site-packages
364 QString distToolsPath = findKritaPythonLibsPath("site-packages");
365 dbgScript << "distToolsPath (site-packages)" << distToolsPath;
366 if (distToolsPath.isEmpty()) {
367 dbgScript << "Cannot find site-packages";
368 return false;
369 }
370 dbgScript << "Found site-packages at" << distToolsPath;
371 paths.append(distToolsPath);
372#else
373 // If using a system Python install, respect the current PYTHONPATH
374 if (runningInBundle) {
375 // We're running from an appimage, so we need our local python
376 QString p = QFileInfo(PYKRITA_PYTHON_LIBRARY).fileName();
377#ifdef Q_OS_MAC
378 QString p2 = p.remove("lib").remove("m.dy").remove(".dy");
379#else
380 QString p2 = p.remove("lib").remove("m.so").remove(".so");
381#endif
382 dbgScript << "\t" << p << p2;
383 originalPath = findKritaPythonLibsPath(p);
384#ifdef Q_OS_MAC
385 // Are we running with a system Python library instead?
386 if (originalPath.isEmpty()) {
387 // Keep the original Python search path.
388 originalPath = QString::fromWCharArray(Py_GetPath());
389 QString d = QFileInfo(PYKRITA_PYTHON_LIBRARY).absolutePath();
390
391 paths.append(d + "/" + p2 + "/site-packages");
392#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
393 paths.append(d + "/" + p2 + "/site-packages/PyQt6");
394#else
395 paths.append(d + "/" + p2 + "/site-packages/PyQt5");
396#endif
397
398 }
399 else {
400#endif
401 paths.append(originalPath + "/lib-dynload");
402 paths.append(originalPath + "/site-packages");
403#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
404 paths.append(originalPath + "/site-packages/PyQt6");
405#else
406 paths.append(originalPath + "/site-packages/PyQt5");
407#endif
408#ifdef Q_OS_MAC
409 }
410#endif
411 }
412 else {
413 // Use the system path
414 originalPath = QString::fromLocal8Bit(qgetenv("PYTHONPATH"));
415 }
416#endif
417
418 QString joinedPaths = paths.join(pathSeparator);
419 if (!originalPath.isEmpty()) {
420 joinedPaths = joinedPaths + pathSeparator + originalPath;
421 }
422 dbgScript << "Setting python paths:" << joinedPaths;
423 qputenv("PYTHONPATH", joinedPaths.toLocal8Bit());
424
425 isPythonPathSet = true;
426 return true;
427}
const Params2D p
QPointF p2
static QString getApplicationRoot()
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References dbgScript, errScript, KoResourcePaths::getApplicationRoot(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, p, and p2.

◆ traceback()

void PyKrita::Python::traceback ( const QString & description)

Print and save (see lastTraceback()) the current traceback in a form approximating what Python would print:

* Traceback (most recent call last):
*   File "/home/shahhaqu/.kde/share/apps/krita/pykrita/pluginmgr.py", line 13, in <module>
*     import kdeui
* ImportError: No module named kdeui
* Could not import pluginmgr.
* 
Todo
How about to show it somewhere else than "console output"?

Definition at line 516 of file utilities.cpp.

517{
518 m_traceback.clear();
519 if (!PyErr_Occurred())
520 // Return an empty string on no error.
521 // NOTE "Return a string?" really??
522 return;
523
524 PyObject* exc_typ;
525 PyObject* exc_val;
526 PyObject* exc_tb;
527 PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
528 PyErr_NormalizeException(&exc_typ, &exc_val, &exc_tb);
529
530 // Include the traceback.
531 if (exc_tb) {
532 m_traceback = "Traceback (most recent call last):\n";
533 PyObject* const arguments = PyTuple_New(1);
534 PyTuple_SetItem(arguments, 0, exc_tb);
535 PyObject* const result = functionCall("format_tb", "traceback", arguments);
536 if (result) {
537 for (int i = 0, j = PyList_Size(result); i < j; i++) {
538 PyObject* const tt = PyList_GetItem(result, i);
539 PyObject* const t = Py_BuildValue("(O)", tt);
540 char* buffer;
541 if (!PyArg_ParseTuple(t, "s", &buffer))
542 break;
543 m_traceback += buffer;
544 }
545 Py_DECREF(result);
546 }
547 Py_DECREF(exc_tb);
548 }
549
550 // Include the exception type and value.
551 if (exc_typ) {
552 PyObject* const temp = PyObject_GetAttrString(exc_typ, "__name__");
553 if (temp) {
554 m_traceback += unicode(temp);
555 m_traceback += ": ";
556 }
557 Py_DECREF(exc_typ);
558 }
559
560 if (exc_val) {
561 PyObject* const temp = PyObject_Str(exc_val);
562 if (temp) {
563 m_traceback += unicode(temp);
564 m_traceback += "\n";
565 }
566 Py_DECREF(exc_val);
567 }
568 m_traceback += description;
569
570 QStringList l = m_traceback.split("\n");
571 Q_FOREACH(const QString &s, l) {
572 errScript << s;
573 }
575}

References errScript, functionCall(), m_traceback, and unicode().

◆ unicode() [1/2]

PyObject * PyKrita::Python::unicode ( const QString & string)
static

Convert a QString to a Python unicode object.

Definition at line 577 of file utilities.cpp.

578{
579 return PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,
580 string.constData(),
581 string.length());
582}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82

References length().

◆ unicode() [2/2]

QString PyKrita::Python::unicode ( PyObject * string)
static

Convert a Python unicode object to a QString.

Definition at line 584 of file utilities.cpp.

585{
586 if (!PyUnicode_Check(string))
587 return QString();
588
589 const int unichars = PyUnicode_GetLength(string);
590 if (0 != PyUnicode_READY(string))
591 return QString();
592
593 switch (PyUnicode_KIND(string)) {
594 case PyUnicode_1BYTE_KIND:
595 return QString::fromLatin1((const char*)PyUnicode_1BYTE_DATA(string), unichars);
596 case PyUnicode_2BYTE_KIND:
597 return QString::fromUtf16(PyUnicode_2BYTE_DATA(string), unichars);
598 case PyUnicode_4BYTE_KIND:
599 return QString::fromUcs4(PyUnicode_4BYTE_DATA(string), unichars);
600 default:
601 break;
602 }
603 return QString();
604}

Member Data Documentation

◆ m_state

PyGILState_STATE PyKrita::Python::m_state
private

Definition at line 224 of file utilities.h.

◆ m_traceback

QString PyKrita::Python::m_traceback
mutableprivate

Definition at line 225 of file utilities.h.

◆ PYKRITA_ENGINE

const char * PyKrita::Python::PYKRITA_ENGINE = "pykrita"
static

Definition at line 219 of file utilities.h.


The documentation for this class was generated from the following files: