主頁 >  其他 > Qt Event(Qt事件)

Qt Event(Qt事件)

2021-06-13 06:48:22 其他

1.事件定義

事件(event)是由系統或者 Qt 本身在不同的時刻發出的,當用戶按下滑鼠,敲下鍵盤,或者是視窗需要重新繪制的時候,都會發出一個相應的事件,一些事件是在對用戶操作做出回應的時候發出,如鍵盤事件等;另一些事件則是由系統自動發出,如計時器事件,

2.事件與信號槽

一般來說,使用 Qt 編程時,我們并不會把主要精力放在事件上,因為在 Qt 中,需要我們關心的事件總會發出一個信號,比如,我們關心的是 QPushButton 的滑鼠點擊,但我們不需要關心這個滑鼠點擊事件,而是關心它的 clicked()信號,

信號槽: signal 由具體物件發出,然后會馬上交給由connect 函式連接的 slot 進行處理,
事件: Qt 使用一個事件佇列對所有發出的事件進行維護,當新的事件產生時,會被追加到事件佇列的尾部,前一個事件完成后,取出后面的事件進行處理,但是,必要的時候,Qt 的事件也是可以不進入事件佇列,而是直接處理的,并且,事件還可以使用“事件過濾器”進行過濾,

總的來說,如果我們使用組件,我們關心的是信號槽;如果我們自定義組件,我們關心的是事件,因為我們可以通過事件來改變組件的默認操作,比如,如果我們要自定義一個 QPushButton,那么我們就需要重寫它的滑鼠點擊事件和鍵盤處理事件,并且在恰當的時候發出 clicked()信號,

3.事件回圈、事件處理函式

我們在 main 函式里面創建了一個 QApplication 物件,然后呼叫了它的 exec()函式,其實,這個函式就是開始 Qt 的事件回圈,在執行 exec()函式之后,程式將進入事件回圈來監聽應用程式的事件,

當事件發生時,Qt 將創建一個事件物件,Qt 的所有事件都繼承于 QEvent 類,在事件物件創建完畢后,Qt 將這個事件物件傳遞給 QObject 的 event()函式,event()函式并不直接處理事件,而是按照事件物件的型別分派給特定的事件處理函式(event handler)

例如在所有組件的父類 QWidget 中,定義了很多事件處理函式,如 keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent ()、mousePressEvent()、mouseReleaseEvent()等,這些函式都是 protected virtual 的,也就是說,我們應該在子類中重定義這些函式,

#include <QApplication> 
#include <QWidget> 
#include <QLabel> 
#include <QMouseEvent> 

class EventLabel : public QLabel 
{ 

protected: 
        void mouseMoveEvent(QMouseEvent *event); 
        void mousePressEvent(QMouseEvent *event); 
        void mouseReleaseEvent(QMouseEvent *event); 
}; 

void EventLabel::mouseMoveEvent(QMouseEvent *event) 
{ 
        this->setText(QString("<center><h1>Move: (%1, %2)</h1></center>").arg(QString::number(event->x()), QString::number(event->y()))); 
} 

void EventLabel::mousePressEvent(QMouseEvent *event) 
{ 
        this->setText(QString("<center><h1>Press: (%1, %2)</h1></center>").arg(QString::number(event->x()), QString::number(event->y()))); 
} 

void EventLabel::mouseReleaseEvent(QMouseEvent *event) 
{ 
        QString msg; 
        msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>",event->x(), event->y()); 
        this->setText(msg); 
} 

int main(int argc, char *argv[]) 
{ 
        QApplication app(argc, argv); 
        EventLabel *label = new EventLabel; 
        label->setWindowTitle("MouseEvent Demo"); 
        label->resize(300, 200); 
        label->show(); 
        return app.exec(); 
}

這里我們繼承了 QLabel 類,重寫了 mousePressEvent、mouseMoveEvent 和 MouseReleaseEvent三個函式,我們并沒有添加什么功能,只是在滑鼠按下(press)、滑鼠移動(move)和滑鼠釋放(release)時把坐標顯示在這個 Label 上面,

4.事件接受與忽略

前面的代碼,我們在子類中重寫了事件函式,以便讓這些子類按照我們的需要完成某些功能,就像下面的代碼:

void MyLabel::mousePressEvent(QMouseEvent * event)
{
        if(event->button() == Qt::LeftButton) {
                // do something
        } else {
                QLabel::mousePressEvent(event);
        }
}

上面的代碼和前面類似,在滑鼠按下的事件中檢測,如果按下的是左鍵,做我們的處理作業,如果不是左鍵,則呼叫父類的函式,這在某種程度上說,是把事件向上傳遞給父類去回應,也就是說,我們在子類中“忽略”了這個事件,

我們可以把 Qt 的事件傳遞看成鏈狀:如果子類沒有處理這個事件,就會繼續向其他類傳遞,其實,Qt的事件物件都有一個 accept()函式和 ignore()函式,正如它們的名字,前者用來告訴 Qt,事件處理函式“接收”了這個事件,不要再傳遞;后者則告訴 Qt,事件處理函式“忽略”了這個事件,需要繼續傳遞,尋找另外的接受者,在事件處理函式中,可以使用 isAccepted()來查詢這個事件是不是已經被接收了,

事實上,我們很少使用 accept()和 ignore()函式,而是像上面的示例一樣,如果希望忽略事件,只要呼叫父類的回應函式即可,

Qt 中的事件大部分是 protected 的,因此,重寫的函式必定存在著其父類中的回應函式,這個方法是可行的,為什么要這么做呢?因為我們無法確認父類中的這個處理函式沒有操作,如果我們在子類中直接忽略事件,Qt 不會再去尋找其他的接受者,那么父類的操作也就不能進行,這可能會有潛在的危險,

在一個情形下,我們必須使用 accept()和 ignore()函式,那就是在視窗關閉的時候,如果你在視窗關閉時需要有個詢問對話框,那么就需要這么去寫:

void MainWindow::closeEvent(QCloseEvent * event)
{
        if(continueToClose()) {
                event->accept();
        } else {
                event->ignore();
        }
}

bool MainWindow::continueToClose()
{
        if(QMessageBox::question(this,
                                            tr("Quit"),
                                            tr("Are you sure to quit this application?"),
                                            QMessageBox::Yes | QMessageBox::No,
                                            QMessageBox::No)
                == QMessageBox::Yes) {
                return true;
        } else {
                return false;
        }
}

這樣,我們經過詢問之后才能正常退出程式,

5.event()函式

事件物件創建完畢后,Qt 將這個事件物件傳遞給 QObject的 event()函式,event()函式并不直接處理事件,而是將這些事件物件按照它們不同的型別,分發給不同的事件處理器(event handler),

event()函式主要用于事件的分發,所以,如果你希望在事件分發之前做一些操作,那么,就需要注意這個 event()函式了,為了達到這種目的,我們可以重寫 event()函式,

例如,如果你希望在視窗中的tab 鍵按下時將焦點移動到下一組件,而不是讓具有焦點的組件處理,那么你就可以繼承 QWidget,并重寫它的 event()函式,已達到這個目的:

bool MyWidget::event(QEvent *event) {
        if (event->type() == QEvent::KeyPress) {
                QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
                if (keyEvent->key() == Qt::Key_Tab) {
                        // 處理 Tab 鍵
                        return true;
                }
        }
        return QWidget::event(event);
}

event()函式接受一個 QEvent 物件,也就是需要這個函式進行轉發的物件,為了進行轉發,必定需要有一系列的型別判斷,這就可以呼叫 QEvent 的 type()函式,其回傳值是 QEvent::Type 型別的列舉,

我們處理過自己需要的事件后,可以直接 return 回去,對于其他我們不關心的事件,需要呼叫父類的 event()函式繼續轉發,否則這個組件就只能處理我們定義的事件了,

event()函式回傳值是 bool 型別,如果傳入的事件已被識別并且處理,回傳 true,否則回傳 false,如果回傳值是 true,QApplication 會認為這個事件已經處理完畢,會繼續處理事件佇列中的下一事件;如果回傳值是 false,QApplication 會嘗試尋找這個事件的下一個處理函式,

event()函式的回傳值和事件的 accept()和 ignore()函式不同,accept()和ignore()函式用于不同的事件處理器之間的溝通,例如判斷這一事件是否處理;event()函式的回傳值主要是通知QApplication 的 notify()函式是否處理下一事件,

為了更加明晰這一點,我們來看看 QWidget 的event()函式是如何定義的:

bool QWidget::event(QEvent *event) {
        switch (e->type()) {
        case QEvent::KeyPress:
                 keyPressEvent((QKeyEvent *)event);
                if (!((QKeyEvent *)event)->isAccepted())
                        return false;
                break;
        case QEvent::KeyRelease:
                keyReleaseEvent((QKeyEvent *)event);
                if (!((QKeyEvent *)event)->isAccepted())
                        return false;
                break;
                // more...
        }
        return true;
}

QWidget 的 event()函式使用一個巨大的 switch 來判斷 QEvent 的 type,并且分發給不同的事件處理函式,在事件處理函式之后,使用這個事件的 isAccepted()方法,獲知這個事件是不是被接受,如果沒有被接受則 event()函式立即回傳 false,否則回傳 true,

另外一個必須重寫 event()函式的情形是有自定義事件的時候,如果你的程式中有自定義事件,則必須重寫 event()函式以便將自定義事件進行分發,否則你的自定義事件永遠也不會被呼叫,

6.事件過濾器

Qt 創建了 QEvent 事件物件之后,會呼叫 QObject 的 event()函式做事件的分發,有時候,你可能需要在呼叫 event()函式之前做一些另外的操作,比如,對話框上某些組件可能并不需要回應回車按下的事件,此時,你就需要重新定義組件的 event()函式,如果組件很多,就需要重寫很多次 event()函式,這顯然沒有效率,為此,你可以使用一個事件過濾器,來判斷是否需要呼叫 event()函式,

QOjbect 有一個 eventFilter()函式,用于建立事件過濾器,這個函式的簽名如下:
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event )
如果 watched 物件安裝了事件過濾器,這個函式會被呼叫并進行事件過濾,然后才輪到組件進行事件處理,在重寫這個函式時,如果你需要過濾掉某個事件,例如停止對這個事件的回應,需要回傳 true

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
 {
         if (obj == textEdit) {
                 if (event->type() == QEvent::KeyPress) {
                         QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                         qDebug() << "Ate key press" << keyEvent->key();
                         return true;
                 } else {
                         return false;
                 }
         } else {
                 // pass the event on to the parent class
                 return QMainWindow::eventFilter(obj, event);
         }
 }

上面的例子中為 MainWindow 建立了一個事件過濾器,為了過濾某個組件上的事件,首先需要判斷這個物件是哪個組件,然后判斷這個事件的型別,

例如,我不想讓 textEdit 組件處理鍵盤事件,于是就首先找到這個組件,如果這個事件是鍵盤事件,則直接回傳 true,也就是過濾掉了這個事件,其他事件還是要繼續處理,所以回傳 false,對于其他組件,我們并不保證是不是還有過濾器,于是最保險的辦法是呼叫父類的函式,

在創建了過濾器之后,下面要做的是安裝這個過濾器,安裝過濾器需要呼叫 installEventFilter()函式,這個函式的簽名如下:
void QObject::installEventFilter ( QObject * filterObj )
這個函式是 QObject 的一個函式,因此可以安裝到任何 QObject 的子類,并不僅僅是 UI 組件,這個函式接收一個 QObject 物件,呼叫了這個函式安裝事件過濾器的組件會呼叫 filterObj 定義的eventFilter()函式,

例如,textField.installEventFilter(obj),則如果有事件發送到textField 組件是,會先呼叫 obj->eventFilter()函式,然后才會呼叫 textField.event(),

當然,你也可以把事件過濾器安裝到 QApplication 上面,這樣就可以過濾所有的事件,已獲得更大的控制權,不過,這樣做的后果就是會降低事件分發的效率,

如果一個組件安裝了多個過濾器,則最后一個安裝的會最先呼叫,類似于堆疊的行為

注意: 如果你在事件過濾器中 delete 了某個接收組件,務必將回傳值設為 true,否則,Qt 還是會將事件分發給這個接收組件,從而導致程式崩潰,

事件過濾器和被安裝的組件必須在同一執行緒,否則,過濾器不起作用,另外,如果在 install 之后,這兩個組件到了不同的執行緒,那么,只有等到二者重新回到同一執行緒的時候過濾器才會有效,

事件的呼叫最終都會呼叫 QCoreApplication 的 notify()函式,因此,最大的控制權實際上是重寫QCoreApplication 的 notify()函式,由此可以看出,Qt 的事件處理實際上是分層五個層次:

  1. 重定義事件處理函式
  2. 重定義 event()函式
  3. 為單個組件安裝事件過濾器
  4. 為 QApplication 安裝事件過濾器
  5. 重定義 QCoreApplication 的 notify()函式

這幾個層次的控制權是逐層增大的,

7.自定義事件

Qt 允許創建自己的事件型別,這在多執行緒的程式中尤其有用,當然,也可以用在單執行緒的程式中,作為一種物件間通訊的機制,那么,為什么需要使用事件,而不是使用信號槽呢?主要原因是,事件的分發既可以是同步的,又可以是異步的,而函式的呼叫或者說是槽的回呼總是同步的,事件的另外一個好處是,它可以使用過濾器,

Qt 中的自定義事件很簡單,同其他類似的庫的使用很相似,都是要繼承一個類進行擴展,在 Qt 中,你需要繼承的類是 QEvent

繼承 QEvent 類,你需要提供一個QEvent::Type 型別的引數,作為自定義事件的型別值,這里的QEvent::Type 型別是 QEvent 里面定義的一個 enum,因此,你是可以傳遞一個 int 的,重要的是,你的事件型別不能和已經存在的 type 值重復,否則會有不可預料的錯誤發生!因為系統會將你的事件當做系統事件進行派發和呼叫,

在 Qt 中,系統將保留0 - 999的值,也就是說,你的事件 type 要大于999. 具體來說,你的自定義事件的 type 要在 QEvent::User 和 QEvent::MaxUser 的范圍之間,其中,QEvent::User 值是1000,QEvent::MaxUser 的值是65535,從這里知道,你最多可以定義64536個事件,相信這個數字已經足夠大了!

但是,即便如此,也只能保證用戶自定義事件不能覆寫系統事件,并不能保證自定義事件之間不會被覆寫,為了解決這個問題,Qt 提供了一個函式:registerEventType(),用于自定義事件的注冊,該函式簽名如下:
static int QEvent::registerEventType ( int hint = -1 );
函式是 static 的,因此可以使用 QEvent 類直接呼叫,函式接受一個 int 值,其默認值為-1,回傳值是創建的這個 Type 型別的值,如果 hint 是合法的,不會發生任何覆寫,則會回傳這個值;如果hint 不合法,系統會自動分配一個合法值并回傳,因此,使用這個函式即可完成 type 值的指定,這個函式是執行緒安全的,因此不必另外添加同步,

你可以在 QEvent 子類中添加自己的事件所需要的資料,然后進行事件的發送,Qt 中提供了兩種發送方式:
static bool QCoreApplication::sendEvent(QObjecy receiver, QEvent event):事件被 QCoreApplication 的 notify()函式直接發送給 receiver 物件,回傳值是事件處理函式的回傳值,使用這個函式必須要在堆疊上創建物件,例如:

QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
QApplication::sendEvent(mainWindow, &event);

static bool QCoreApplication::postEvent(QObject receiver, QEvent event):事件被 QCoreApplication 追加到事件串列的最后,并等待處理,該函式將事件追加后會立即回傳,并且注意,該函式是執行緒安全的,另外一點是,使用這個函式必須要在堆上創建物件,例如:

QApplication::postEvent(object, new MyEvent(QEvent::registerEventType(2048)));

這個物件不需要手動 delete,Qt 會自動 delete 掉!因此,如果在 post 事件之后呼叫 delete,程式可能會崩潰,另外,postEvent()函式還有一個多載的版本,增加一個優先級引數,具體請參見API,通過呼叫 sendPostedEvent()函式可以讓已提交的事件立即得到處理,
如果要處理自定義事件,可以重寫 QObject 的 customEvent()函式,該函式接收一個 QEvent 物件作為引數,可以像前面介紹的重寫 event()函式的方法去重寫這個函式:

void CustomWidget::customEvent(QEvent *event) {
        CustomEvent *customEvent = static_cast<CustomEvent *>(event);
        // ....
}

另外,你也可以通過重寫 event()函式來處理自定義事件:

bool CustomWidget::event(QEvent *event) {
        if (event->type() == MyCustomEventType) {
                CustomEvent *myEvent = static_cast<CustomEvent *>(event);
                // processing...
                return true;
        }
        return QWidget::event(event);
}

這兩種辦法都是可行的,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286895.html

標籤:其他

上一篇:新的TLS攻擊讓黑客可以對安全站點發起跨協議攻擊

下一篇:用戶登錄 JWT TOKEN

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more