♥ 學習筆記Learning 程式語言 Coding

[程式] QT – Chap.7 Reimplementing Event Handlers (2/3) C++

如果是一個按鍵事件,我們將會指派QEvent物件給QKeyEvent,並且確認看看是哪個按鍵被按下。如果這個按鍵是Tab鍵,我們會做一些處理並且回傳true告訴QT我們已經處理了這個事件,如果我們回傳false,QT將會傳遞事件給它的父部件(parent widget)。

使用QAction去將幾個按鍵綁在一起是更高級的實作方法。例如,如果goToBeginningOfLine()goToBeginningOfDocument()是CodeEditor小工具的public slots,而且CodeEditor使用MainWindow類別做為中央部件,我們可以增加幾個按鍵組合,如下:

 1: MainWindow::MainWindow()
 2: {
 3:     editor = new CodeEditor;
 4:     setCentralWidget(editor);
 5: 
 6:     goToBeginningOfLineAction =
 7:             new QAction(tr("Go to Beginning of Line"), this);
 8:     goToBeginningOfLineAction->setShortcut(tr("Home"));
 9:     connect(goToBeginningOfLineAction, SIGNAL(activated()),
 10:             editor, SLOT(goToBeginningOfLine()));
 11: 
 12:     goToBeginningOfDocumentAction =
 13:             new QAction(tr("Go to Beginning of Document"), this);
 14:     goToBeginningOfDocumentAction->setShortcut(tr("Ctrl+Home"));
 15:     connect(goToBeginningOfDocumentAction, SIGNAL(activated()),
 16:             editor, SLOT(goToBeginningOfDocument()));
 17:     ...
 18: }

 

這會讓我們更容易新增指令(Command)到選單或工具列,就像我們在第三章所看到的一樣。如果指令沒有顯是在使用者介面上,QAction 物件可以用QShortcut取代,這個類別藉由QAction去支援按鍵組合。

預設的情況下,按鍵組合設定是使用QAction 或 QShortcut,而使用QAction::setShortcutContext() 與QShortcut::setContext()則可以改變按鍵的組合。

另一種常見的事件類型是計時事件,當大部分的事件都是因為使用者行為而產生的,只有計時事件允許應用程式在規律的時間內自行做處理,計時事件可以被用來實作捲軸組合或其他的動畫,或簡單的更新顯示介面。

為了示範計時事件,我們將實作一個Ticker小工具,如7.1所示。這個小工具會顯示一個純文字橫幅,每30微秒移動一個像素,如果這個小工具比文字內容還寬,這個文字將會重複直到填滿整個小工具介面。

image
Figure 7.1. The Ticker widget

這是標頭檔。

 1: #ifndef TICKER_H
 2: #define TICKER_H
 3: 
 4: #include <QWidget>
 5: 
 6: class Ticker : public QWidget
 7: {
 8:     Q_OBJECT
 9:     Q_PROPERTY(QString text READ text WRITE setText)
 10: 
 11: public:
 12:     Ticker(QWidget *parent = 0);
 13: 
 14:     void setText(const QString &newText);
 15:     QString text() const { return myText; }
 16:     QSize sizeHint() const;
 17: 
 18: protected:
 19:     void paintEvent(QPaintEvent *event);
 20:     void timerEvent(QTimerEvent *event);
 21:     void showEvent(QShowEvent *event);
 22:     void hideEvent(QHideEvent *event);
 23: 
 24: private:
 25:     QString myText;
 26:     int offset;
 27:     int myTimerId;
 28: };
 29: 
 30: #endif

 

我們重新實作四個事件處理,其中三個我們還沒有在之前看過,包含timerEvent()、showEvent()和hideEvent()

現在,來看看這個實作。

 1: #include <QtGui>
 2: 
 3: #include "ticker.h"
 4: 
 5: Ticker::Ticker(QWidget *parent)
 6:     : QWidget(parent)
 7: {
 8:     offset = 0;
 9:     myTimerId = 0;
 10: }

建構子初始化offset 變數為0,這個文字藉由offset值來描繪X座標,計時ID(Timer IDs)總是非零,所以我們使用0去表示沒有計時器已經開始。

 1: void Ticker::setText(const QString &newText)
 2: {
 3:     myText = newText;
 4:     update();
 5:     updateGeometry();
 6: }

setText()函式設定需要顯示的文字,它可以呼叫update()去要求重繪或是updateGeometry()去提醒任何有責任控制Ticker小工具大小的版面管理者。

 1: QSize Ticker::sizeHint() const
 2: {
 3:     return fontMetrics().size(0, text());
 4: }
 5: 

 

sizeHint() 函式回傳這些文字所需空間的理想大小。QWidget::fontMetrics()回傳QFontMetrics 物件藉此查詢更多關於字體有關的訊息。在這種情形下,我們可以要求所需的大小(第一個變數QFontMetrics::size() 是一個不太需要的旗標,所以我們傳0就好。

 

 

以下,下一篇待續。>W<
這樣居然才寫完7.1節而已Q___________Q
今天上班好無聊喔!甚麼時候才能給我下一個任務的資料呢?

About the author

蕾咪

蕾咪,來自台東,卻不定期旅居歐洲的工程師女孩,身兼作家、部落客、創業家等多重身份。畢業於台大電子所,曾在義大利商與美商擔任研發工程師;走訪世界後,發現對台灣有段割捨不了的愛,讓我們一起努力成為想要的自己吧!:) 合作邀稿請聯繫:[email protected]

8 Comments

  • 呵呵 別擔心。:) 忙考試重要。

    # 生活

    實際上,需要平衡生活與工作是很困難的,
    尤其在台灣我們要抵抗加班的壓力與金錢的誘惑(笑),
    每段日子,我也需要花許多時間來掙扎,避免在別人眼裡過太爽。
    但是,當你想要忠於自己的人生時,並不是只有努力工作才代表你活過。

    這時候,就要對於某些無情或苛刻的批判練習充耳不聞,
    那些一大部分討厭你的人,也許正在犧牲他們的健康感情家庭去成就事業。

    這只是我個人的選擇而已,但並不代表示對的喔!?^__________^
    我的生活其實並沒有你想像的讓人羨慕,很多人也過著這樣的生活,只是我寫下來而已。

    # 外語

    說實話,我的英文並沒有很好。:) 目前只能說有紮實的國中英文程度。
    其實,國中課本裡面的英文對話都非常實用,把他學透了,盡量用用看,生活是沒問題的。

    口說語聽力的部分,我曾經花過一些時間聽ICRT與BBC News,進步會出現,但是很緩慢。
    聽不懂並不是障礙,但是你要先試著大量的聽,沒有逐字稿也沒關係,,聽出語感來。
    口說的部分,則是短暫的使用過My ET來練習,我覺得那是一個不錯的線上練習軟體。
    最好的方式是找一個夥伴,只能用英文聊天,或是去尋找外籍生來語言交換。

    這些都是方法,而我的英文口說快速進步是在國外工作必須大量的使用英文。
    在研究所期間,我的指導教授訓練我 信件往來都必須使用英文,而論文也是純英文寫作。

    英文文法部分,最簡單的原則,就是去觀察動詞,把句子中的動詞畫出來。

    # C# 程式語言學習

    這個語言我比較不熟悉,我的經驗學習一個不熟悉的語言,例如最近我學QT。
    先去找大家最推薦的那一本好書,然後看是要以專案為目標,還是完成甚麼功能。

    練習裡面的範例(不是只是看喔!>W< 要真正的實作看看,熟悉那些語法。) 當你碰到專案(Project)或說一個作業的時候。 1. 先去思考你想要怎麼解決它?做法是甚麼? 2. 然後再思考你有甚麼資源可以解決它?利用那些現有資源(語法)去組織起來解決方法。 3. 最後將你想出的解決方案實踐出來,然後一邊測試一邊調整細節,直到完成為止。 這三個步驟是我解決問題常用的步驟。 第一步是幫助你釐清腦中的幾種解決方案。 第二步是分析你的解決方案,有哪些現有資源可以應用。 第三步是實際行動的去解決你的問題,並且一邊調整方向,直到完成。 事實上,人生很多問題都可以用這三步驟去解決。:) 因此,我認為最後有沒有選擇走工程這不是重點,重點是妳有沒有學會我們被訓練出來的邏輯。 所以試試看吧!:) 以你的問題為例,先把你的影像處理問題去拆解成幾個單一的功能,再分解實做。 我遇過幾次影像處理的問題(軟體硬體),但是這個問法太廣泛,我不太知道怎麼回答你。:)

  • Rami 姊姊:
    你好,看了你的網頁和你的經歷後,覺得你對電腦方面好有熱忱,
    我也是資工系的學生,但是日前對打程式這方面和電腦方面有著大大的困擾,
    老實說我沒有對資工有特別的興趣,但是卻又不想半途而廢,
    所以想問問不知道蕾咪姐姐能不能跟我分享一下你當初在碰電腦的瓶頸和一些經驗,
    還有打程式的一些學習方式和技巧,可以讓自己的能力大大提升,還有有什麼方法讓自己
    對電腦方面能有更多的知識和一些技能!!
    希望你能與我分享你的經驗,謝謝!:>

    • Dear Eva:

      很高興看到你的留言,歡迎隨時回來再找我聊聊。

      # 其實我跟你一樣有迷惘過。

      說我對於電腦科學非常有熱情,我想有點言重了。

      因為事實上,我也曾經”非常討厭”寫程式,看到程式就心煩就害怕。
      寫下網誌裡的一些教學筆記,一方面就是為了強迫我自己面對這件事。
      而另一方面,我希望可以幫助一些像我一樣害怕寫程式的人,一起解決問題。

      不過,我們有一樣的心情,就是不想要半途而廢,也不甘心半途而廢。
      我想不管是任何專業技能,在磨練的過程中,都必然經過一些辛苦的過程。
      即使你曾經多麼的熱愛它,更別說一般人的感受了。

      只是有些人不引以為杵,而有些人(就像我)變得會有點逃避。
      但是當你面對了,你就成長了。

      # 根據電腦方面的技能。

      如果你目前還是資工系的在學生,我想盡力的去克服問題,
      完成你該繳交的程式作業,就是最好的訓練。

      也許這樣的訓練,短期中並不會讓你感到成就感,
      甚至你無法感覺到自己正在進步,但是相信我累積下來絕對很可觀。

      解決程式作業遇到困難時,我覺得培養一個「向他人學習的態度」是很重要的。
      你可以選擇向身邊的同學請教討論,也可以選擇在網路上搜尋看看別人是怎麼解決這問題的。
      為什麼對方想的出這個解法?別人是用甚麼樣的程式寫作風格在寫作?別人思考邏輯的順序是怎麼樣的…

      很多時候,你需要依賴自己去重組好幾種解法,才能變成屬於你的解決方法。
      但是蕾咪認為這是非常好的邏輯思考訓練,因為在現實中大部分的事情都是複合性的問題。

      # 程式語言,其實就是一種語言,就像英文一樣。

      我們學習英文需要大量的背單字(指令集)、學習文法(程式邏輯),
      但是最終的目的,都是為了溝通而存在的,
      差異在於程式語言是「人類與機器溝通的語言」。

      因此,能夠用這個語言”對話”與”寫文章”,才是我們最大的目的;
      而我們才能夠命令機器替我們做好更多的事情。

      這也就是工程師,事實上在全世界是一個很Portable(可移植性))的行業。
      並不容易受到語言的隔閡,程式語言是全世界工程師共通的語言。

      另外,建議你先專注精通一種語言就好,例如C語言或C++。
      因為他們是程式語言的基礎,精通一種語言,能夠應用在不同的演算法、繪圖或網路協定等。
      之後如果因為工作需要學習另一種語言,絕對會比其他人還要更容易上手的。

      # 找自己有興趣的部份去創造成就感。

      我想這是我認為最重要的部分。
      可以想像一下,哪些用資訊科技創造出來的部分是你最喜歡的。

      是I-phones那樣的智慧型手機、還是網路上隨時可以下載的有趣APP。
      個人覺得電腦科學是一個很棒的能力,因為你甚至可以輕易的和其他專業整合。

      例如:
      有些朋友他們對於行銷有興趣,選擇成為行銷工程師,以分析資訊科技市場為導向。
      有些朋友喜歡法律,於是開始向科技法律靠攏,成為專利工程師。
      甚至有些人喜歡寫小APP,就這樣為自己賺進收入。
      也有人喜歡撰寫教學文件,最後成為補習班老師或講師。

      每一種領域都有適合不同人格特質的選擇,沒有人規定念資工系就必須要當RD工程師。
      不過如果你也喜歡用自己的能力將想像中的技術實現出來,那麼RD工程師或許就很適合你。

      #

      話說回來,台灣是個資訊科技很不錯的國家。

      我的義大利同事告訴我說,
      台灣是個很有名的國家,因為有非常多優秀的科技產品來自於台灣。

      我還蠻以身為台灣人為榮的,希望你以後也是。^^ 一起加油吧!再找我聊聊囉!

      • 謝謝你跟我分享這麼多唷!!

        有時候會覺得自己的夢想和真正去實踐的時候,好不一樣!!

        有時候更不知道該從何去著手

        那麼Rami姊姊有對現在的電腦工作的生活感到疲倦嗎??

        我聽一個也是讀資訊系學長說:他現在的工作很難找!!

        • 不知道現在資訊產業的發展是如何??

          rami姊姊~我現在是大三的學生,

          你覺得讀資訊科技還有須要繼續升學讀研究所的必要性嗎??

          或是說大學畢業就先去企業實習工做這樣是否會比較好呢??

          看看自己是否對這個領域有興趣或未來發展的必要性??

          • Dear Eva,

            在《顛倒思考題》這本書裡面,有一頁這樣寫著。
            「不想念書的時候,就去工作吧!」

            我大三大四時,也有想同的迷惘,因為我不特別想要念研究所,我不知道我要研究甚麼(笑)。
            於是,我隨意翻了一本書,那本書正好就這樣寫著。

            我的建議不見得是好的,因為每個人並不相同。
            蕾咪是個任性的傢伙,從小到大都是秉持著自己的熱情去選擇職涯。

            所以,當熱情消失的時候,我便選擇停下來放空,跑去工作了。
            我相信老天爺隨時都會準備好一條適合自己的路,只要你沒有放棄準備好你自己。

            因此,我的經驗是在我大學畢業後,因緣際會跑去了工研院工作,
            但是我是個沒辦法停止閱讀學習的人,那是我興趣的一部分。

            所以,我在下班後(18:30~),每天都花了約兩到三小時(20:00~22:30)唸書,念念多益或去圖書館亂看。
            我喜歡自己隨時都在成長進步的感覺,後來在考前一兩個月,在家人與朋友的鼓勵下報考研究所。
            所以就在下班之餘,把一位好心學姐寄給我的課本念了一遍,那年剛好運氣好就考上了研究所。

            後來,開始念研究所時,我一度很自我懷疑這是我要的嗎?
            不過我相信老天爺的安排(笑),一定是想整整我(大笑),覺得我太混了。

            我在入學時,給自己設定了幾個目標,要求自己一定要達成,最後也都達成了。
            其實我的目標都很小:P,也很簡單,甚至很基本,但是不要求自己可能就做不到。
            1. 我希望我可以克服對程式的恐懼,能靠自己完成自己的專案。
            2. 我希望我可以用英文完成我的碩士論文,鍛鍊自己的英文寫作。
            3. 我希望我可以開始學德文,完成我從小想去德國看看的心願。
            4. 我希望我可以了解甚麼是創業,還有了解別人為什麼說我適合創業。
            5. 我希望我可以維持好感情生活,不要因為太忙而忽略。
            6. 我希望我可以重新愛上電腦科學,找回自己的熱情。

            甚麼事情比較好,你要問你自己?^^
            你希望你以後變成怎麼樣的人?而你希望自己成為甚麼樣的人?這都比別人的看法都還要重要。
            我看過很多只念大學就比研究生態度還優秀的學弟妹,也看過有人經歷過研究所生活產生的蛻變。

            重點是你希望自己能夠做甚麼?又能夠得到甚麼?
            研究所的生活並不是美好的代名詞,也不會保證你從此過著幸福快樂的日子。
            更多時候,他是強迫你學會孤獨、學會獨立的解決問題、學會思考未來下一步。
            學會接受批評與挑戰、學會了解這世界上很多都跟你想的不一樣,學會面對無力感與處理壓力…

            想清楚你要甚麼,才不會被牽著走^^ 一起加油吧!

            Rami

        • 其實,我不知道該怎麼準確的定義夢想耶!
          我只能說「能夠一直去做自己想做的事情,那會是一種幸福。」
          所以,與其把想做的事情,扣一個夢想的大帽子,不如替它貼下”接下來待辦事項”的標籤。

          其實,我還蠻喜歡我的工作的。
          RD的工作其實很單純,就是應用現有的技術與知識,去解決目前存在的問題。
          唯一會讓蕾咪坐不住的就是我喜歡”人”,喜歡與人互動,一直和電腦講話我會無聊到爆炸XD 然後變笨~
          所以團隊合作對蕾咪來說是個必備良藥,只要讓我感覺到我屬於某一份子,就會比較有動力做好事。

          我不曉得工作難不難找,也許那會是我以後會碰到的問題。
          但我的想法是,即使工作難找是一種趨勢,並不代表你就必須成為那其中之一。:)

          何不想想有沒有辦法,讓你自己成為好找工作的一個人呢?
          即使真的找不到工作,我相信資訊人的技術也是屬於一群適合微型創業的種族。

          EVA,依照你的回答,我還並不了解你,你可以告訴我,你喜歡甚麼樣的生活嗎?^^

          • rami姊姊,抱歉這麼久才回覆你,最近忙著考試!!

            其實我好嚮往你目前的生活,可以一邊工作又可以一邊持續著自己的

            旅行以及享受美食和攝影!

            我覺得目前的我,好像是一個倦怠期和過度期,導致開始厭倦現在的

            生活以及失去目前的方向,目前得自己我也不知道以後會不會從事這

            方面的工作,以及相關的方向!

            目前想先盡自己的能力把系上的科目做一個結束,畢業後想先暫時當

            個背包客,去澳洲打工旅遊,順便換個環境,想給自己重新出發的機會,

            並且給自己一段的時間沉澱和學習,想想自己真正想做得是什麼,就

            想你說的「能夠一直去做自己想做的事情,那會是一種幸福。」

            我想當自己找到幸福的時候,自然而然興趣就出現了,當然金錢也就

            隨之而來!!

            順道一提,rami姊姊是如何加強自己的外語能力的呢??

            我想讓口說和聽力變得更好,但是都沒有練習的機會,所以程度都沒

            什麼大幅度的進步,不知道你有沒有什麼好方法??

            還有像是 C# 語言 , 如果要學習我應該要從何下手呢??

            因為目前在做專題要做 “影像處理” 的部分 ,要用到 C# 的程式,

            不知道你有沒有什麼經驗,和如何操作此程式的一些方法?? ︿︿

            Good luck for you and myself ! =目

Leave a Comment