程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python知識:需要優先掌握的一些Qt知識點

編輯:Python

PyQt - Major Classes (tutorialspoint.com)

說明:PyQt API 包含 400 多個類。 QObject 類位於類層次結構的頂部。而常見的又實用的一些知識點需要優先掌握,本篇就將一些常用要點展現出來。

一、面向對象設計

QObject 類位於類層次結構的頂部。它是所有 Qt 對象的基類。此外,QPaintDevice 類是所有可繪制對象的基類。因此:

        ​​​​​​​QApplication 類管理 GUI 應用程序的主要設置和控制流程。它包含主事件循環,在其中處理和調度由窗口元素和其他源生成的事件。它還處理系統范圍和應用程序范圍的設置。

        QWidget 類,派生自 QObject 和 QPaintDevice 類,是所有用戶界面對象的基類。 QDialog 和 QFrame 類也派生自 QWidget 類。他們有自己的子類系統。

下圖描述了其層次結構中的一些重要類。

  • QWidget是可視組件的頂級基礎。

  •  對話框的頂級類

  • 與繪制相關的基本類是QPainterDevice 

 二、最常見的Widgets.

Sr.No.Widgets & Description1

QLabel

Used to display text or image

2

QLineEdit

Allows the user to enter one line of text

3

QTextEdit

Allows the user to enter multi-line text

4

QPushButton

A command button to invoke action

5

QRadioButton

Enables to choose one from multiple options

6

QCheckBox

Enables choice of more than one options

7

QSpinBox

Enables to increase/decrease an integer value

8

QScrollBar

Enables to access contents of a widget beyond display aperture

9

QSlider

Enables to change the bound value linearly.

10

QComboBox

Provides a dropdown list of items to select from

11

QMenuBar

Horizontal bar holding QMenu objects

12

QStatusBar

Usually at bottom of QMainWindow, provides status information.

13

QToolBar

Usually at top of QMainWindow or floating. Contains action buttons

14

QListView

Provides a selectable list of items in ListMode or IconMode

15

QPixmap

Off-screen image representation for display on QLabel or QPushButton object

16

QDialog

Modal or modeless window which can return information to parent window

三、主窗口QMainWindow 

        一個典型的基於 GUI 的應用程序的頂層窗口是由 QMainWindow 小部件對象創建的。上面列出的一些小部件在此主窗口中占據指定位置,而其他小部件則使用各種布局管理器放置在中央小部件區域。

下圖顯示了 QMainWindow 框架 -

 

Main Window[編輯]

Qt提供了下列主視窗管理和相關的用戶界面組件的類別:

  • QMainWindow:提供一個標准的應用程序主視窗。當中可以包括菜單、工具欄、狀態欄、停駐組件等組件。
  • QDockWidget:提供了一個可用於創建彈簧工具調色板或輔助窗口的widget。Dock widgets可以移、關閉、浮動為外部視窗。
  • QToolBar:提供了一個通用的工具欄widget,可以放入一些不同的action有關的工具,如按鈕、下拉菜單、comboboxes和spin boxes。

四、圖形界面

        Qt的圖形用戶界面的基礎是QWidget。Qt中所有類型的GUI組件如按鈕、標簽、工具欄等都派生自QWidget,而QWidget本身則為QObject的子類。Widget負責接收鼠標,鍵盤和來自窗口系統的其他事件,並描繪了自身顯示在屏幕上。每一個GUI組件都是一個widget,widget還可以作為容器,在其內包含其他Widget。

        QWidget不是一個抽象類別。並且可以被放置在一個已存在的用戶界面中;若是Widget沒有指定父Widget,當它顯示時就是一個獨立的視窗、或是一個頂層widget。QWidget顯示能力包含了透明化及Double-Buffering。Qt提供一種托管機制,當Widget於創建時指定父對象,就可把自己的生命周期交給上層對象管理,當上層對象被釋放時,自己也被釋放。確保對象不再使用時都會被刪除。

        以下是一個QGraphicsView的例子,實現滑動的窗體效果,工具欄和圖片均為場景中的Item。

4.1 繪圖三套件

        QGraphicsView用來顯示一個滾動視圖區的QGraphicsScene內容。QGraphicsScene提供了QGraphicsItem的容器功能。通常與QGraphicsView一起使用來描述可視化圖形項目。

         QGraphicsScene提供了一個視圖的場景,通過在這樣一個場景之上加入不同的QGraphicsItem來構建視圖。而QGraphicsView則提供了一個widget來顯示QGraphicsScene的內容。所以要想成功構建一個視圖,這三個元素共同搭配,合成整體。

五、信號與槽 

Qt利用信號與槽(signals/slots)機制取代傳統的callback來進行對象之間的溝通。當操作事件發生的時候,對象會發提交一個信號(signal);而槽(slot)則是一個函數接受特定信號並且執行槽本身設置的動作。信號與槽之間,則透過QObject的靜態方法connect來鏈接。

信號在任何執行點上皆可發射,甚至可以在槽裡再發射另一個信號,信號與槽的鏈接不限定為一對一的鏈接,一個信號可以鏈接到多個槽或多個信號鏈接到同一個槽,甚至信號也可連接到信號。

以往的callback缺乏類型安全,在調用處理函數時,無法確定是傳遞正確類型的參數。但信號和其接受的槽之間傳遞的資料類型必須要相符合,否則編譯器會提出警告。信號和槽可接受任何數量、任何類型的參數,所以信號與槽機制是完全類型安全。

信號與槽機制也確保了低耦合性,發送信號的類別並不知道是哪個槽會接受,也就是說一個信號可以調用所有可用的槽。此機制會確保當在"連接"信號和槽時,槽會接受信號的參數並且正確執行。

六、布局管理 

        布局管理類別用於描述一個應用程序的用戶界面中的Widget是如何放置。當視窗縮放時,布局管理器會自動調整widget的大小、位置或是字號,確保他們相對的排列和用戶界面整體仍然保有可用性。

        Qt內置的布局管理類型有:QHBoxLayout、QVBoxLayout、QGridLayout和QFormLayout。這些類別繼承自QLayout,但QLayout非繼承自QWidget而是直接源於QObject。他們負責widget的幾何管理。想要創建更復雜的版面配置,可以繼承QLayout來自定義版面配置管理員。

  • QHBoxLayout:配置widget成橫向一列
  • QVBoxLayout:配置widget成垂直一行
  • QGridLayout:配置widget在平面網格
  • QFormLayout:配置widget用於2欄標簽- field

七 一個可以移動畫面的圖形案例

[cpp]  view plain copy

#include <QtCore>  
#include <QtGui>  
#include <QtSvg>  
/*程序中用到了svg格式的圖片,所以需包含QtSvg*/  
#define PAGE_COUNT 5  
/*定義滑動窗體的窗體數*/  

定義工具欄,NviBar繼承自QGraphicsRectItem,用法與QGraphicsItem類似。

[cpp]  view plain copy

class NaviBar : public QObject, public QGraphicsRectItem  
{  
    Q_OBJECT  
public:  
    NaviBar();  
    void setPageOffset(qreal ofs);  
signals:  
    void pageSelected(int page);  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event);  
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);  
private:  
    QList<QGraphicsSvgItem*> m_icons;  
    QGraphicsRectItem *m_cursor;  
};  

函數實現

[cpp]  view plain copy

#define ICON_SIZE 50  
#define ICON_PAD 4  
NaviBar::NaviBar() : QGraphicsRectItem()  
{  
    setRect(0, 0, 5 * ICON_SIZE, ICON_SIZE);  
    setPen(Qt::NoPen);  
    QStringList names;  
    names << "map" << "web" << "home" << "weather" << "contacts";  
    for (int i = 0; i < names.count(); ++i) {  
        QString fname = names[i];  
        fname.prepend(":/icons/");  
        fname.append("-page.svg");  
        QGraphicsSvgItem *icon = new QGraphicsSvgItem(fname);  
        icon->setParentItem(this);  
        const int dim = ICON_SIZE - ICON_PAD * 2;  
        qreal sw = dim / icon->boundingRect().width();  
        qreal sh = dim / icon->boundingRect().height();  
        icon->setTransform(QTransform().scale(sw, sh));  
        icon->setZValue(2);  
        m_icons << icon;  
    }  
    m_cursor = new QGraphicsRectItem;  
    m_cursor->setParentItem(this);  
    m_cursor->setRect(0, 0, ICON_SIZE, ICON_SIZE);  
    m_cursor->setZValue(1);  
    m_cursor->setPen(Qt::NoPen);  
    m_cursor->setBrush(QColor(Qt::white));  
    m_cursor->setOpacity(0.6);  
}  
void NaviBar::setPageOffset(qreal ofs)  
{  
    m_cursor->setPos(ofs * ICON_SIZE, 0);  
    for (int i = 0; i < m_icons.count(); ++i) {  
        int y = (i == static_cast<int>(ofs + 0.5)) ? ICON_PAD : ICON_PAD * 2;  
        m_icons[i]->setPos(i * ICON_SIZE + ICON_PAD, y);  
        m_icons[i]->setOpacity(1);  
    }  
}  
void NaviBar::mousePressEvent(QGraphicsSceneMouseEvent *event)  
{  
    emit pageSelected(static_cast<int>(event->pos().x() / ICON_SIZE));  
}  
void NaviBar::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)  
{  
    painter->setBrush(Qt::white);  
    painter->setOpacity(0.2);  
    painter->drawRect(option->rect.adjusted(-20, ICON_PAD, 20, 0));  
}  

定義視圖

[cpp]  view plain copy

class ParallaxHome: public QGraphicsView
{
    Q_OBJECT
public:
    QGraphicsScene m_scene;
    NaviBar *m_naviBar;
    QGraphicsPixmapItem *m_wallpaper;
    QTimeLine m_pageAnimator;
    qreal m_pageOffset;
    QList<QGraphicsPixmapItem*> m_items;
    QList<QPointF> m_positions;
public:
    ParallaxHome(QWidget *parent = 0)
            : QGraphicsView(parent)
            , m_pageOffset(-2) {
        setupScene();
        setScene(&m_scene);
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setFrameShape(QFrame::NoFrame);
        setWindowTitle("Parallax Home");
        connect(&m_pageAnimator, SIGNAL(frameChanged(int)), SLOT(shiftPage(int)));
        m_pageAnimator.setDuration(500);
        m_pageAnimator.setFrameRange(0, 100);
        m_pageAnimator.setCurveShape(QTimeLine::EaseInCurve);
        pageChanged(static_cast<int>(m_pageOffset));
    }
signals:
    void pageChanged(int page);
public slots:
    void slideRight() {
        if (m_pageAnimator.state() != QTimeLine::NotRunning)
            return;
        int edge = -(m_pageOffset - 1);
        if (edge < PAGE_COUNT)
            slideBy(-1);
    }
    void slideLeft() {
        if (m_pageAnimator.state() != QTimeLine::NotRunning)
            return;
        if (m_pageOffset < 0)
            slideBy(1);
    }
    void slideBy(int dx) {
        int start = m_pageOffset * 1000;
        int end = (m_pageOffset + dx) * 1000;
        m_pageAnimator.setFrameRange(start, end);
        m_pageAnimator.start();
    }
    void choosePage(int page) {
        if (m_pageAnimator.state() != QTimeLine::NotRunning)
            return;
        if (static_cast<int>(-m_pageOffset) == page)
            return;
        slideBy(-page - m_pageOffset);
    }
private slots:
    void shiftPage(int frame) {
        int ww = width();
        int hh = height() - m_naviBar->rect().height();
        int oldPage = static_cast<int>(-m_pageOffset);
        m_pageOffset = static_cast<qreal>(frame) / qreal(1000);
        int newPage = static_cast<int>(-m_pageOffset);
        m_naviBar->setPageOffset(-m_pageOffset);
        if (oldPage != newPage)
            emit pageChanged(newPage);
        int ofs = m_pageOffset * ww;
        for (int i = 0; i < m_items.count(); ++i) {
            QPointF pos = m_positions[i];
            QPointF xy(pos.x() * ww, pos.y() * hh);
            m_items[i]->setPos(xy + QPointF(ofs, 0));
        }
        int center = m_wallpaper->pixmap().width() / 2;
        const int parallax = 3;
        int base = center - (ww / 2) - (PAGE_COUNT >> 1) * (ww / parallax);
        int wofs = base - m_pageOffset * ww / parallax;
        m_wallpaper->setPos(-wofs, 0);
    }
protected:
    void resizeEvent(QResizeEvent *event) {
        Q_UNUSED(event);
        layoutScene();
    }
    void keyPressEvent(QKeyEvent *event) {
        if (event->key() == Qt::Key_Right)
            slideRight();
        if (event->key() == Qt::Key_Left)
            slideLeft();
        event->accept();
    }
private:
    void layoutScene() {
        int ww = width();
        int hh = height();
        m_scene.setSceneRect(0, 0, PAGE_COUNT * ww - 1, hh - 1);
        centerOn(ww / 2, hh / 2);
        int nw = m_naviBar->rect().width();
        int nh = m_naviBar->rect().height();
        m_naviBar->setPos((ww - nw) / 2, hh - nh);
        shiftPage(m_pageOffset * 1000);
    }
    void setupScene() {
        qsrand(QTime::currentTime().second());
        QStringList names;
        names << "brownies" << "cookies" << "mussels" << "pizza" << "sushi";
        names << "chocolate" << "fish" << "pasta" << "puding" << "trouts";
        for (int i = 0; i < PAGE_COUNT * 2; ++i) {
            QString fname = names[i];
            fname.prepend(":/images/");
            fname.append(".jpg");
            QPixmap pixmap(fname);
            pixmap = pixmap.scaledToWidth(200);
            QGraphicsPixmapItem *item = m_scene.addPixmap(pixmap);
            m_items << item;
            qreal x = (i >> 1) + (qrand() % 30) / 100.0;
            qreal y = (i & 1) / 2.0  + (qrand() % 20) / 100.0;
            m_positions << QPointF(x, y);
            item->setZValue(1);
        }
        m_naviBar = new NaviBar;
        m_scene.addItem(m_naviBar);
        m_naviBar->setZValue(2);
        connect(m_naviBar, SIGNAL(pageSelected(int)), SLOT(choosePage(int)));
        m_wallpaper = m_scene.addPixmap(QPixmap(":/icons/surfacing.png"));
        m_wallpaper->setZValue(0);
        m_scene.setItemIndexMethod(QGraphicsScene::NoIndex);
    }
};

main函數

[cpp]  view plain copy

#include "parallaxhome.moc"  
int main(int argc, char *argv[])  
{  
    QApplication app(argc, argv);  
    ParallaxHome w;  
    w.resize(360, 640);  
    w.show();  
    return app.exec();  
}  


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved