1. 程式人生 > >Qt自定義控制元件的建立與初步使用(二)之圖片上繪製文字、箭頭、曲線

Qt自定義控制元件的建立與初步使用(二)之圖片上繪製文字、箭頭、曲線

本文目的:編輯自定義控制元件的介面ui,並在圖片上添文字、箭頭、曲線、開啟、儲存等功能。並說明了如何去使用這個編輯好的ui介面控制元件!

上次簡單的說明了如何去建立Qt自定義控制元件,當時還是對其瞭解不夠深刻,現在看來,QT自定義控制元件就是你事先把介面寫好(一般基於QWidget基類),然後再把它寫入QT自定義控制元件的工程【可參考Qt自定義控制元件的建立與初步使用(一)這篇部落格】中去,最後放到別的工程中,通過簡單的拖拽和拷貝就可以用了。那怎麼樣去做和使用這個自定義的控制元件呢?又要注意什麼呢?具體分為三大步,下面給大家娓娓道來!

配置:Qt creator5.7,Qt 5.7+VS2013(64位)(有人喜歡用後者,全憑個人愛好,我用的是creator),本篇案例的說明用的是Qt5.6(因為本人的電腦裝的是Qt5.6,公司的電腦裝的是Qt5.7),建議最好用Qt5.7,但實際操作中不會有太大差別。

一、建立基類是QWidget的Qt Application工程,把介面寫好。
1.建立一個Qt Application工程,命名為 sof_Interface,基類是QWidget,然後一路下一步,這樣你就完成了一個工程的建立(先在這個工程上把需要的介面寫好)

2.開啟.ui介面,此處為5個功能:開啟圖片、儲存圖片、在圖片上新增文字、曲線、箭頭符號。拖拽5個pushbotton、1個QLabel、1個QLineEdit、1個QDialogbottonbox,並按圖所示排號介面,並選中,右鍵點選轉到槽,從而建立相關的槽函式。並新增程式碼。

sof_Interface.h程式碼

<span style="font-family:Times New Roman;font-size:14px;">#ifndef SOF_INTERFACE_H
#define SOF_INTERFACE_H

#include <QWidget>
#include <QAbstractButton>
namespace Ui {
class sof_Interface;
}

class sof_Interface : public QWidget
{
    Q_OBJECT

public:
    explicit sof_Interface(QWidget *parent = 0);
    ~sof_Interface();

    void paint(QImage&theImage);
    enum Type{
        type1,
        type2,
        type3,
    };

private slots:
    void on_doOpen_clicked();//開啟圖片
    void on_doSave_clicked();//儲存圖片
    void on_buttonBox_clicked(QAbstractButton *button);//ok、cancel
    void on_mou_Track_clicked();//曲線
    void on_arrow_Edit_clicked();//箭頭
    void on_text_Edit_clicked();//文字
private:
    Ui::sof_Interface *ui;
    QString curFile;                      //開啟檔名
    bool isOpen;
    Type path_type;                       //畫的圖形種類
    QImage  image,tempImage;              //原圖、快取圖片
    QPixmap pic;                          //用於顯示圖片
    bool isDrawing;
    QPoint begin,end;
    QPoint end_pos;                       //滑鼠釋放時的位置
    QString Text;                         //儲存文字變數
protected:
 void mousePressEvent(QMouseEvent *e);    //滑鼠按下事件
 void mouseMoveEvent(QMouseEvent *e);     //滑鼠移動事件
 void mouseReleaseEvent(QMouseEvent *e);  //滑鼠釋放事
 void paintEvent(QPaintEvent *);          //重繪事件
};

#endif // SOF_INTERFACE_H
</span>

sof_Interface.cpp中程式碼

<span style="font-family:Times New Roman;font-size:14px;">#include "sof_interface.h"
#include "ui_sof_interface.h"
#include <QFileDialog>
#include <QPainter>
#include <QMessageBox>
#include <QMouseEvent>
#include <QlineEdit>
sof_Interface::sof_Interface(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::sof_Interface)
{
    ui->setupUi(this);
    isOpen=false;
    path_type=type1;//初始化
    isDrawing=false;//初始化
 }

sof_Interface::~sof_Interface()
{
    delete ui;
}
/////////////////////////////槽函式/////////////////////////////
void sof_Interface::on_doOpen_clicked()                               //開啟圖片槽函式
{
     QString fileName = QFileDialog::getOpenFileName(
                       this, "開啟圖片",
                       "",
                       "圖片格式 (*.bmp *.jpg *.jpeg *.png)");
      if(fileName !=NULL)
        {
         image.load(fileName);
         curFile=fileName;
         isOpen=true;
        }
      update();
}

void sof_Interface::on_doSave_clicked()                                //儲存圖片槽函式
{
    QString path = QFileDialog::getSaveFileName(
                 this, tr("儲存圖片"),
         "","圖片格式 (*.bmp *.jpg *.jpeg *.png)");
    image.save(path);
}

void sof_Interface::on_buttonBox_clicked(QAbstractButton *button)      //lineEdit命令列輸入槽函式
{
    QString str;

    if(ui->buttonBox->button(QDialogButtonBox::Ok)  == button) //判斷按下的是否為"確定”按鈕
    {
        if(!ui->lineEdit->text().isEmpty())                    //判斷lineEdit是否為空,不為空返回0
        {
            str += ui->lineEdit->text()+"\n";                  //str連線lineEdit中的內容
            Text=str;                                          //在圖片上寫入lineEdit中輸入的文字
            str="";
        }

    }
    else if(button == ui->buttonBox->button((QDialogButtonBox::Cancel)))
      {
           ui->lineEdit->clear();

      }
}

void sof_Interface::on_mou_Track_clicked()                            //曲線槽函式
{
    path_type=type1;
}

void sof_Interface::on_arrow_Edit_clicked()                           //箭頭槽函式
{
    path_type=type2;
}

void sof_Interface::on_text_Edit_clicked()                            //文字槽函式
{
    path_type=type3;
}

////////////////////////////滑鼠事件////////////////////////////


void sof_Interface::mousePressEvent(QMouseEvent *e)                  //滑鼠按下事件
{
   begin=e->pos();
}

void sof_Interface::mouseMoveEvent(QMouseEvent *e)                   //滑鼠移動事件
{
    end=e->pos();

    if(path_type==type1)  //只有path_type==type1才繪製在image上(原圖),這時isDrawing=false;
    {
        isDrawing=false;
        paint(image);
    }
    else                  //其他path_type全繪製在tempImage上(緩衝圖上)
    {
        isDrawing=true;
        tempImage=image;
        paint(tempImage);
    }
}

void sof_Interface::mouseReleaseEvent(QMouseEvent *e)                //滑鼠釋放事件
{
      end=e->pos();
      isDrawing=false;
      paint(image);

}

/////////////////////////paintEvent事件////////////////////////////
void sof_Interface::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    if(isDrawing)
      p.drawImage(0,0,tempImage);
    else
      p.drawImage(0,0,image);

    if(isOpen=true)   //開啟圖片操作
    {
        pic=QPixmap::fromImage(image);
        QPainter painter(this);
        painter.drawPixmap(0,0,748,480,pic);
    }
}

////////////////////////每個畫圖的函式////////////////////////////
void sof_Interface::paint(QImage &theImage)
{
    QPainter pp(&theImage);

    pp.setCompositionMode(QPainter::CompositionMode_SourceIn);    //設定畫刷的組合模式CompositionMode_SourceOut這個模式為目標影象在上。
    pp.setPen(QPen(QBrush(Qt::red), 2, Qt::SolidLine));           //設定畫筆(顏色,線寬,樣式(實線))
    pp.setRenderHint(QPainter::Antialiasing, true);               //設定線段反鋸齒
    QFont font = pp.font();                                       //設定字型
    font.setPixelSize(20);                                        //改變字型大小
    font.setBold(false);                                          //字型是否加粗
    pp.setFont(font);                                             //設定字型

    if(path_type==type1)                                          //曲線
    {
        pp.drawLine(begin,end);
        begin=end;
    }

    if(path_type==type2)                                          //箭頭
    {
        float x1 = begin.x();                                     //取points[0]起點的x
        float y1 = begin.y();                                     //取points[0]起點的y
        float x2 = end.x();                                       //取points[count-1]終點的x
        float y2 = end.y();                                       //取points[count-1]終點的y
        float l = 10.0;                                           //箭頭的長度
        float a = 0.5;                                            //箭頭與線段角度
        float x3 = x2 - l * cos(atan2((y2 - y1) , (x2 - x1)) - a);//計算箭頭的終點(x3,y3)
        float y3 = y2 - l * sin(atan2((y2 - y1) , (x2 - x1)) - a);
        float x4 = x2 - l * sin(atan2((x2 - x1) , (y2 - y1)) - a);//計算箭頭的終點(x4,y4)
        float y4 = y2 - l * cos(atan2((x2 - x1) , (y2 - y1)) - a);
        pp.drawLine(x2,y2,x3,y3);                                 //繪製箭頭(x2,y2,x3,y3)
        pp.drawLine(x2,y2,x4,y4);                                 //繪製箭頭(x2,y2,x4,y4)
        pp.drawLine(begin,end);                                   //繪製主幹箭頭(begin,end)
    }

    if(path_type==type3)                                          //文字
    {
       pp.drawText(begin.x(),begin.y(),Text);
    }

    update();
}
</span>

main.pp中程式碼

<span style="font-family:Times New Roman;font-size:14px;">#include "sof_interface.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    sof_Interface w;
    w.show();

    return a.exec();
}</span>

3.介面執行效果,還可以儲存哦,注意圖片格式只能載入.jpg.jpeg.png.bmp,需要擴充套件的自己在程式碼中新增吧!當然還可以更改介面背景色等,自己去改哦~這只是個demo。

二、將自己第一步寫的sof_Interface工程.h和.cpp的程式碼拷貝到自定義控制元件工程的.h和.cpp中即可寫成自定義控制元件工程了,注意程式碼不能完全貼上複製哦,注意自己建立工程的類名,除非你和我的一樣。然後編譯後見一下.dll和.lib,並放到相應的designer中,具體可參考【Qt自定義控制元件的建立與初步使用(一)這篇部落格】。

三、這樣你再新建立任意一個工程,你都可以在Qt creator或Qt 設計師中找到自己建立的控制元件,然後拖拽到工程的ui介面中,最後拷貝自定義控制元件.h和.cpp到這個新工程的工程目錄下,注意和第二大步不一樣哦~,就可以編譯執行啦。再次就不給效果圖啦~

相關推薦

Qt定義控制元件建立初步使用圖片繪製文字箭頭曲線

本文目的:編輯自定義控制元件的介面ui,並在圖片上添文字、箭頭、曲線、開啟、儲存等功能。並說明了如何去使用這個編輯好的ui介面控制元件! 上次簡單的說明了如何去建立Qt自定義控制元件,當時還是對其瞭解不夠深刻,現在看來,QT自定義控制元件就是你事先把介面寫好(一般基於QWi

定義控制元件三部曲檢視篇——RecyclerView系列之一簡單使用

絕望的時候不要那麼絕望,高興的時候不要那麼高興,是你慢慢會學會的。 ——董卿 轉了一年多,又回來繼續做Android。果然還是看到程式碼最讓我興奮……但有些事,沒經歷過,總歸還是遺憾的。在VIVO的遊戲中心,有一個特別炫酷的功能: 這個功能就是使

定義控制元件三部曲檢視篇——瀑布流容器WaterFallLayout實現

前言:只要在前行,夢想就不再遙遠 系列文章: 前面兩節講解了有關ViewGroup的onMeasure、onLayout的知識,這節我們深入性地探討一下,如何實現經常見到的瀑布流容器,本節將實現的效果圖如下: 從效果圖中可以看出這裡要完成的

C#定義控制元件程式設計輕鬆入門1

前 言 話說,許多新手在接觸C#的時候都覺得C#使用起來特別容易方便,相對C++來說沒有那麼多的繁瑣,比如C++每次在使用一個函式,都要先在標頭檔案中宣告一遍,而C#宣告和實現都在一起,立馬可以用。而且不會一會要寫指標一會兒要寫引用,如果是遇到VC那些控制代碼就把頭給搞大。 隨著

定義控制元件三部曲檢視篇——RecyclerView系列ItemDecoration

從來不跌倒不算光彩,每次跌倒後能再站起來,才是最大的榮耀。 一、新增分割線 1.1 引入ItemDecoration 在上一篇中,我們講解了RecyclerView的基本使用方法,但有個問題:為什麼Item之間沒有分割線呢?其實,給RecyclerView新

四十九c#Winform定義控制元件-下拉框表格

前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr

Qt定義控制元件建立初步使用

本篇部落格的目的是簡單介紹:建立一個用QLabel類來顯示圖片的自定義控制元件的編寫。在寫自定義控制元件的過程中遇到了很多的難題,但都慢慢解決了,本人對Qt自定義控制元件的認識還不深刻,做的不對的地方,還請大家指出,我會盡快修改,免得誤導他人! 配置:Qt creator5

編寫Qt Designer定義控制元件——如何建立並使用Qt定義控制元件

    http://blog.csdn.net/giselite/article/details/12622429   在使用Qt Designer設計窗體介面時,我們可以使用Widget Box裡的窗體控制元件非常方便的繪製介面,比如拖進去一個按鈕,一個文字編輯器等。雖然Qt Designer裡的控制元

Qt定義控制元件以及控制元件的提升

關於 在使用Qt做介面時,通用、常用的控制元件重複設定屬性是件麻煩的事情,比如密碼輸入框,一個密碼輸入框要設定許多屬性,比如密文顯示,長度,只能輸入固定字元型別,禁止複製等等,一個專案裡面有時會用到很多密碼框,每設定一個密碼框就會導致對上面的屬性重複設定,會導

新手定義控制元件,建立屬於自己的下拉重新整理(一)---Android,ListView實現IOS的彈性效果

前言 相信很多童鞋對於控制元件的下拉重新整理都比較熟悉吧,常用的PullToRefresh開源庫和Google自帶的SwipeRefreshLayout大家肯定也很熟悉吧,但作為一個Android開發新手,對於自定義控制元件和自定義View來實現一些效果肯定還

我的新書《Android定義控制元件入門實戰》出版啦

 前言:當你回首往事時,不以虛度年華而悔恨,不以碌碌無為而羞恥,那你就可以驕傲的跟自己講,你不負此生 念念碎: 兩年前,為了深入研究自定義控制元件,堅持在CSDN上,以每週或每兩週更新一篇部落格的頻率,出版了《Android自定義控制元件三部曲》系列,中間因為業務太忙

Qt定義控制元件大全+UI定製+輸入法

做各種各樣的介面的時候,經常需要做一排按鈕用於切換到對應介面,俗稱導航按鈕或者導航選單,參照過各種各樣的主介面導航佈局,特意編寫導航按鈕自定義控制元件,結合各種情況,繼承自QPushButton。已整合在QUC自定義控制元件中。 /** * 導航按鈕控制元件 作者:f

Qt編寫定義控制元件37-發光按鈕會呼吸的痛

一、前言 這個控制元件是好早以前寫的,已經授權過好幾個人開源過此控制元件程式碼,比如紅磨坊小胖,此控制元件並不是來源於真實需求,而

[WPF 定義控制元件]建立包含CheckBox的ListBoxItem

1. 前言 Xceed wpftoolkit提供了一個CheckListBox,效果如下: 不過它用起來不怎麼樣,與其這樣還不如參考UWP的ListView實現,而且動畫效果也很好看: 它的樣式如下: <ListViewItemPresenter ContentTransitions="

Qt定義控制元件儀表盤1--簡單的貼圖儀表盤

0、前言   學程式首先要輸出hell world,學電子要先來個流水燈。學Qt,那就必須先來個自定義控制元件,若有人問我從哪個下手,我推薦儀表盤,可簡可繁,從低配到高配齊全,可入門也可進階。 1、儀表盤解析 以常見的、傳統的儀表盤為例,分解儀表盤的元素,主要有邊框、刻度、數字、指標(或數

Qt定義控制元件儀表盤2--QPaint繪製儀表盤

0、前言     前面一篇文章寫道了儀表盤的特點,實現了一個貼圖的儀表盤,屬於低配版本的儀表盤。    主要是有任何改動時候就需要重新設計圖片,不能適配不同控制元件大小,即使讓它自由拉伸,但儀表盤放大縮小時候顯示效果會變差。這篇文章設計了一個自己繪製的儀表盤,有背景錶盤

Qt定義控制元件儀表盤3--雷達掃描圖

1、設計思想 雷達掃描圖,在影視作品中見到較多,比如飛機雷達、艦艇雷達,有一個掃描線轉圈代表雷達一週旋轉或一個批次的收發,發現目標就在錶盤上標記位置。和汽車儀表盤類似,汽車儀表盤有底盤背景圖、同圓、刻度、刻度值、旋轉的指標。能在汽車儀表盤的基礎上略作修改,比如指標換成帶有餘輝的掃描扇面,就能完成一個雷達掃描圖

定義控制元件 輪盤 來源於GITHUB記錄,筆記

自定義控制元件:輪盤抽獎 -------邏輯程式碼(輪盤的類)首先要寫一個類繼承SurfaceView 實現Callback和Runnable方法: //所使用的包 import android.content.Context; import android.graphics.Ca

定義控制元件 輪盤 來源於GITHUB記錄,筆記

自定義控制元件:輪盤抽獎 -------邏輯程式碼(輪盤的類)首先要寫一個類繼承SurfaceView 實現Callback和Runnable方法: //所使用的包 import android.content.Context; import android.

vue esview 控制元件拖拽問題Vue.directiove定義命令

控制元件拖拽問題(二) initDropEvents是繫結在bind中的(droppable.js) 而這個droppable是在install_derictive.js中定義的定義命令, Vue.directive(‘droppable’,droppable)