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 434 of file utilities.cpp.

435{
436 if (Py_IsInitialized()) {
437 warnScript << "Python interpreter is already initialized, not initializing again";
438 } else {
439 dbgScript << "Initializing Python interpreter";
440 Py_InitializeEx(0);
441 if (!Py_IsInitialized()) {
442 errScript << "Could not initialize Python interpreter";
443 }
444#if THREADED
445 s_pythonThreadState = PyGILState_GetThisThreadState();
446 PyEval_ReleaseThread(s_pythonThreadState);
447#endif
448 }
449}
#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 157 of file utilities.cpp.

162{
163 if (!arguments) {
164 errScript << "Missing arguments for" << moduleName << functionName;
165 return nullptr;
166 }
167 PyObject* const func = itemString(functionName, moduleName);
168 if (!func) {
169 errScript << "Failed to resolve" << moduleName << functionName;
170 return nullptr;
171 }
172 if (!PyCallable_Check(func)) {
173 traceback(QString("Not callable %1.%2").arg(moduleName).arg(functionName));
174 return nullptr;
175 }
176 PyObject* const result = PyObject_CallObject(func, arguments);
177 if (!result)
178 traceback(QString("No result from %1.%2").arg(moduleName).arg(functionName));
179
180 return result;
181}
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 auto arguments = PyTuple_New(0);
150 PyObject* const result = functionCall(functionName, moduleName, arguments);
151 Py_DECREF(arguments);
152 if (result)
153 Py_DECREF(result);
154 return bool(result);
155}
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 612 of file utilities.cpp.

613{
614 return PyUnicode_Check(string);
615}

◆ 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 192 of file utilities.cpp.

193{
194 if (PyObject* const value = itemString(item, moduleDict(moduleName)))
195 return value;
196
197 errScript << "Could not get item string" << moduleName << item;
198 return 0;
199}
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 201 of file utilities.cpp.

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

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 183 of file utilities.cpp.

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

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 210 of file utilities.cpp.

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

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 219 of file utilities.cpp.

220{
221 if (PyObject* const module = moduleImport(moduleName)) {
222 PyObject* args = Py_BuildValue("(O)", module);
223 PyObject* ret = functionCall(handler, "krita", args);
224 Py_DECREF(args);
225 return ret;
226 }
227 return 0;
228}
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 230 of file utilities.cpp.

231{
232 QString result;
233 result.swap(m_traceback);
234 return result;
235}
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 237 of file utilities.cpp.

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

References dbgScript.

◆ libraryUnload()

void PyKrita::Python::libraryUnload ( )
static

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

Definition at line 463 of file utilities.cpp.

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

◆ maybeFinalize()

void PyKrita::Python::maybeFinalize ( )
static

Finalize the Python interpreter. Not guaranteed to work.

Definition at line 451 of file utilities.cpp.

452{
453 if (!Py_IsInitialized()) {
454 warnScript << "Python interpreter not initialized, no need to finalize";
455 } else {
456#if THREADED
457 PyEval_AcquireThread(s_pythonThreadState);
458#endif
459 Py_Finalize();
460 }
461}

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 478 of file utilities.cpp.

479{
480 return kritaHandler(moduleName, "moduleGetActions");
481}
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 483 of file utilities.cpp.

484{
485 return kritaHandler(moduleName, "moduleGetConfigPages");
486}

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 499 of file utilities.cpp.

500{
501 PyObject* const module = moduleImport(moduleName);
502 if (module)
503 if (PyObject* const dictionary = PyModule_GetDict(module))
504 return dictionary;
505
506 traceback(QString("Could not get dict %1").arg(moduleName));
507 return 0;
508}

References traceback().

◆ moduleHelp()

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

Get the help text defined by a module.

Definition at line 488 of file utilities.cpp.

489{
490 QString r;
491 PyObject* const result = kritaHandler(moduleName, "moduleGetHelp");
492 if (result) {
493 r = unicode(result);
494 Py_DECREF(result);
495 }
496 return r;
497}
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 510 of file utilities.cpp.

511{
512 PyObject* const module = PyImport_ImportModule(moduleName);
513 if (module)
514 return module;
515
516 traceback(QString("Could not import %1").arg(moduleName));
517 return 0;
518}

References traceback().

◆ prependPythonPaths() [1/3]

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

Definition at line 644 of file utilities.cpp.

645{
646 Q_ASSERT("Dir entry expected to be valid" && sys_path);
647 return bool(prependStringToList(sys_path, path));
648}
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 617 of file utilities.cpp.

618{
619 PyObject* sys_path = itemString("path", "sys");
620 return bool(sys_path) && prependPythonPaths(path, sys_path);
621}
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 623 of file utilities.cpp.

624{
625 PyObject* sys_path = itemString("path", "sys");
626 if (!sys_path)
627 return false;
628
630 QStringList reversed_paths;
631 std::reverse_copy(
632 paths.begin()
633 , paths.end()
634 , std::back_inserter(reversed_paths)
635 );
636
637 Q_FOREACH(const QString & path, reversed_paths)
638 if (!prependPythonPaths(path, sys_path))
639 return false;
640
641 return true;
642}

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 296 of file utilities.cpp.

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

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

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 583 of file utilities.cpp.

584{
585 return PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,
586 string.constData(),
587 string.length());
588}
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 590 of file utilities.cpp.

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

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: