日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Qt, Python(一)

發(fā)布時(shí)間:2023/12/20 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt, Python(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://antkillerfarm.github.io/

Qt主循環(huán)

這篇文章有個(gè)大概的比較和說明:

http://blog.chinaunix.net/uid-20754930-id-1877623.html

以下是我針對(duì)Qt5代碼(2015.4)的一個(gè)研究。

QApplication::exec

QGuiApplication::exec

QCoreApplication::exec

QEventLoop::exec

QEventLoop::processEvents

QEventDispatcher::processEvents

再以下就和具體的平臺(tái)相關(guān)了。

Windows平臺(tái):

QEventDispatcherWin32::processEvents

它的實(shí)現(xiàn)主要是GetMessage+WaitForMultipleObjects,如上文中對(duì)MiniGUI的主循環(huán)所述。

Unix平臺(tái):

QEventDispatcherUNIX::processEvents

QEventDispatcherUNIXPrivate::doSelect

這個(gè)函數(shù)主要使用select系統(tǒng)調(diào)用來監(jiān)聽事件源。

Android平臺(tái):

QAndroidEventDispatcher::processEvents

QUnixEventDispatcherQPA::processEvents

QEventDispatcherUNIX::processEvents

以下和Unix平臺(tái)相同。

Qt多線程中connect的使用

近日在研究OpenGL多線程處理時(shí),偶然看到了如下代碼:

http://download.csdn.net/detail/zhoukuanbin/7669187

沒有CSDN賬號(hào)的讀者,也可以在這里下載:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/Qt/MyGlTest

粗看代碼,發(fā)現(xiàn)并無特殊的OpenGL處理,理論上應(yīng)該無法達(dá)到一個(gè)線程處理渲染,另一個(gè)線程處理貼圖的目標(biāo)。但實(shí)際編譯運(yùn)行代碼,又確實(shí)可用。因此這里面一定有什么原因。

void ThreadGl::run() {connect(this, SIGNAL(SigCopy()), this, SLOT(Copy()));printf("ID 0:%x\n", currentThreadId());while(1){if(!m_bEndFlag){break;}usleep(16000);emit SigCopy();}qDebug("Copy End\n"); }void ThreadGl::Copy() {m_glWidgets -> OnTimeOut(m_pImage, m_Formal, m_pthId); }

這段代碼引起了我的注意。粗一看,connect函數(shù)連接的SIGNAL和SLOT都屬于同一個(gè)對(duì)象。而connect函數(shù)的第5個(gè)參數(shù)(這是個(gè)有默認(rèn)值的可省略參數(shù))的默認(rèn)值為Qt::AutoConnection。

這是Qt官方對(duì)Qt::AutoConnection的解釋:

  • If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.

按照字面上的意思,既然SIGNAL和SLOT都屬于同一個(gè)對(duì)象,那么這里的Qt::AutoConnection就等同于Qt::DirectConnection。而Qt::DirectConnection與直接調(diào)用SLOT函數(shù)是一個(gè)效果。

于是這里將emit SigCopy();替換為Copy();,結(jié)果程序運(yùn)行出錯(cuò)。

再試一下,將connect函數(shù)的第5個(gè)參數(shù)設(shè)為Qt::DirectConnection,同樣有問題。

而如果將之設(shè)為Qt::QueuedConnection的話,程序運(yùn)行一切正常。

綜上,Qt在這里的處理,顯然認(rèn)為SIGNAL和SLOT屬于不同的線程。

那么判斷的依據(jù)是什么呢?

這里有必要對(duì)emit SigCopy();中emit背后的戲法做一個(gè)剖析。

眾所周知,emit并非C++關(guān)鍵字,而屬于Qt擴(kuò)展的一部分。Qt為了處理這些擴(kuò)展,引入了moc工具作為預(yù)處理工具。

而moc處理之后,emit SigCopy();就變成了QMetaObject::activate

QMetaObject::activate中使用以下代碼,判定信號(hào)接收者的線程是否和信號(hào)發(fā)送者的一致。

const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;

于是問題轉(zhuǎn)化為receiver->d_func()->threadData是怎么來的呢?

答案在QObject::QObject中:

d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();

從這里可以看出所謂信號(hào)接收者的線程,實(shí)際上是接收者對(duì)象創(chuàng)建時(shí)所處的線程。

回到原來的問題。ThreadGl雖然是Qt的線程對(duì)象,但它本身卻是在主線程中創(chuàng)建的,所以以它為接收者,實(shí)際上就是以主線程為接收者。

顯然這個(gè)例子代碼并沒有真正實(shí)現(xiàn)OpenGL多線程處理,所有的OpenGL操作實(shí)際上都是在主線程完成的。

Python

教程

http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

國人寫的一個(gè)中文教程。

PyPI

PyPI是一個(gè)Python語言的軟件庫管理軟件,它的官網(wǎng)是:

https://pypi.python.org/pypi

用戶可以在這里查找自己需要的Python包。

Ubuntu下的安裝方法是:

sudo apt-get install python-pip

使用方法是:

pip install <package name>

有的python包因?yàn)榘豢梢浦驳亩M(jìn)制文件,使用pip安裝的時(shí)候會(huì)出錯(cuò)。這時(shí),可在ubuntu官網(wǎng)搜索安裝相應(yīng)的python包。

對(duì)于可移植的python包,直接使用pip安裝即可,在ubuntu官網(wǎng)搜也搜不到的。

iPython

ipython是一個(gè) python 的交互式 shell,比默認(rèn)的python shell 好用得多,支持變量自動(dòng)補(bǔ)全,自動(dòng)縮進(jìn),支持 bash shell 命令,內(nèi)置了許多很有用的功能和函數(shù)。

在較新的ipython版本中,添加了ipython notebook的功能,彌補(bǔ)了ipython shell下代碼不易保存等缺點(diǎn),并且在使用 –pylab inline選項(xiàng)后,可以在代碼執(zhí)行后立即顯示運(yùn)行結(jié)果(包括圖片,數(shù)據(jù)表格等),因此在數(shù)據(jù)分析中運(yùn)用十分廣泛。

sudo apt-get install ipython ipython-notebook

軟件發(fā)布工具

distutils

distutils是python自帶的軟件發(fā)布工具。它的安裝腳本一般叫做setup.py,對(duì)應(yīng)的配置文件叫做setup.cfg。

它的文檔參見:

https://docs.python.org/2/distutils/index.html

distutils-extra

distutils-extra在distutils的基礎(chǔ)上做了擴(kuò)展,提供諸如i18n之類的支持。如果沒有安裝,會(huì)報(bào)如下錯(cuò)誤:

error: error in setup.cfg: command 'build' has no such option 'i18n'

安裝方法:

sudo apt-get install python-distutils-extra

setuptools

setuptools是一個(gè)更強(qiáng)大的distutils擴(kuò)展,它也是PyPI的基礎(chǔ)。它的安裝腳本通常以ez_setup.py的形式出現(xiàn)。

它的文檔參見:

https://pythonhosted.org/setuptools/setuptools.html

安裝方法:

sudo apt-get install python-setuptools

Easy Install

setuptools提供的一個(gè)工具,可從網(wǎng)絡(luò)下載安裝外部依賴文件。

它的文檔參見:

https://pythonhosted.org/setuptools/easy_install.html

PyGObject

談起Python調(diào)用GTK+的話題,在GTK+ 2的時(shí)代可以使用PyGTK庫。它的官網(wǎng)是:

http://www.pygtk.org/

但由于PyGTK庫本質(zhì)上來說,使用了和一般的Python調(diào)用C庫一樣的方法,因此每導(dǎo)入一個(gè)庫,都需要編寫大量的接口文件。GNOME工程有那么多項(xiàng)目,采用這種辦法顯然是不太可行的。

于是,GNOME工程發(fā)起了GObject Introspection項(xiàng)目。眾所周知,GNOME工程諸多項(xiàng)目的基石是GObject。這是一個(gè)很成功的類型系統(tǒng),使用該系統(tǒng)可以獲得遠(yuǎn)比普通C庫更強(qiáng)的支持。GObject Introspection項(xiàng)目的目標(biāo)就是創(chuàng)建一個(gè)用于跨語言綁定的中間層。這個(gè)項(xiàng)目的官網(wǎng)是:

https://wiki.gnome.org/Projects/GObjectIntrospection

隨著GObject Introspection項(xiàng)目的進(jìn)展,越來越多的語言綁定開始使用這套系統(tǒng),python也不例外。PyGObject項(xiàng)目就是這種方法的成果,目前它已經(jīng)取代了PyGTK庫,成為GTK+ 3時(shí)代Python調(diào)用GTK+的官方方案。它的官網(wǎng)是:

https://wiki.gnome.org/Projects/PyGObject

相關(guān)的API參考文檔可參見:

http://lazka.github.io/pgi-docs/

指南文檔可參見:

http://python-gtk-3-tutorial.readthedocs.org/en/latest/

安裝方法:

Ubuntu下,可以執(zhí)行:

sudo apt-get install python-gi python3-gi

Windows下,有個(gè)PyGObject for Windows項(xiàng)目,該項(xiàng)目的官網(wǎng)是:

http://sourceforge.net/projects/pygobjectwin32/files/

PyGObject的helloworld程序可參見:

https://github.com/antkillerfarm/antkillerfarm_crazy/blob/master/python/pygtk-helloworld.py

這里必須指出的是,PyGObject依賴的接口文件只有在dev包中才有。安裝相關(guān)Glib項(xiàng)目時(shí),一定要選擇名稱以-dev結(jié)尾的包。

Sqlite

Ubuntu下的安裝方法是:

sudo apt-get install sqlite

Python自帶了pysqlite包,用于調(diào)用sqlite。

pysqlite的helloworld程序可參見:

https://github.com/antkillerfarm/antkillerfarm_crazy/blob/master/python/pysqlite-helloworld.py

可以使用sqlite_bro軟件包,查看sqlite數(shù)據(jù)庫。安裝方法:

sudo pip install sqlite_bro

python調(diào)用GTK函數(shù)的一般規(guī)則

眾所周知,GTK庫是用C語言編寫的,其相關(guān)的文檔提供的也是C函數(shù)的接口,python接口的文檔相對(duì)較少,獲得也不太容易。因此有必要掌握一下這方面基本的命名規(guī)則。(這里只講方法,對(duì)深層次的調(diào)用原理不做探究。)

1)類初始化函數(shù)

C:GtkWidget * gtk_button_new (void);

python:button = Gtk.Button()

這里除了把C函數(shù)式的寫法,替換成python的類的寫法之外,并無其他差異。

2)普通類成員函數(shù)

C:void gtk_container_add (GtkContainer *container, GtkWidget *widget);

python:button.add(image)

可以看出,C函數(shù)的第一個(gè)表示self類指針的參數(shù)被省略掉了。

3)回調(diào)函數(shù)

這里以按鈕的click事件回調(diào)為例:

C:void user_function (GtkButton *button, gpointer user_data)

python:

button.connect("clicked", self.playToggled)

def playToggled(self, w):

這里的情況要復(fù)雜的多。首先在事件回調(diào)注冊(cè)的時(shí)候,由于我們并沒有給user_data賦值,因此照理說playToggled函數(shù),只有button這一個(gè)參數(shù)。但實(shí)際傳遞給playToggled函數(shù)的有兩個(gè)參數(shù),self是一個(gè)用于占位的參數(shù),w對(duì)應(yīng)button,沒有東西對(duì)應(yīng)user_data。

4)用于輸出的參數(shù)

C:void gst_message_parse_error (GstMessage *message, GError **gerror, gchar **debug);

python:err, debug = message.parse_error()

這個(gè)例子中的gerror和debug都是用于輸出的參數(shù)。如果只想得到其一,還可用以下方法:

debug = message.parse_error()[2]

5)枚舉類型

C:

enum GstSeekFlags {GST_SEEK_FLAG_FLUSH,... }

python:Gst.SeekFlags.FLUSH

6)宏常量

C:#define GST_CLOCK_TIME_NONE ((GstClockTime) -1)

python:Gst.CLOCK_TIME_NONE

7)類型轉(zhuǎn)換

大多數(shù)情況下,類型轉(zhuǎn)換自動(dòng)完成,并無什么問題。這里只討論特殊的情況。

C:

gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,GST_SEEK_TYPE_SET, time_nanoseconds,GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))

python:

self.player.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH, Gst.SeekType.SET,\time_nanoseconds, Gst.SeekType.NONE, Gst.CLOCK_TIME_NONE)

這里首先按照一般的方法,將C代碼轉(zhuǎn)化成python代碼。但是運(yùn)行之后,產(chǎn)生如下錯(cuò)誤:

OverflowError: long too big to convert

究其原因,gst_element_seek的最后一個(gè)參數(shù)是uint64類型的。但python原生并不支持該類型,而是將之轉(zhuǎn)換成int類型(實(shí)際上是int64類型),這樣的話,GST_CLOCK_TIME_NONE的值顯然超出了int64所能表示的范圍。

解決的辦法是使用ctypes庫,將

Gst.CLOCK_TIME_NONE

改為

c_long(Gst.CLOCK_TIME_NONE).value

Python中的括號(hào)

Python主要有三種數(shù)據(jù)類型:字典、列表、元組。其分別由花括號(hào),中括號(hào),小括號(hào)表示。如:

字典:dic={‘a(chǎn)’:12,’b’:34}

列表:list=[1,2,3,4]

元組:tup=(1,2,3,4)

總結(jié)

以上是生活随笔為你收集整理的Qt, Python(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。