Golang使用lxn/walk做GUI介面開發:郵件群發器

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

我也是剛剛使用walk這個組件,很多控制項介面不熟悉,把我上次發的郵件群發器修改成圖形介面的,線程發送郵件,gob庫儲存資料等。只提供作學習交流,僅供參考(介面很爛)。

接下來是main.go的代碼:

// Multi-SendEmail project main.gopackage mainimport (    "bufio"    "encoding/gob"    "errors"    "fmt"    "io"    "net/smtp"    "os"    "strconv"    "strings"    "time")import (    "github.com/lxn/walk"    . "github.com/lxn/walk/declarative")type ShuJu struct {    Name    string    Pwd     string    Host    string    Subject string    Body    string    Send    string}func SendMail(user, password, host, to, subject, body, mailtype string) error {    fmt.Println("Send to " + to)    //fmt.Println(user, password, host, to, subject, body, mailtype)    hp := strings.Split(host, ":")    auth := smtp.PlainAuth("", user, password, hp[0])    var content_type string    if mailtype == "html" {        content_type = "Content-Type: text/html;charset=UTF-8"    } else {        content_type = "Content-Type: text/plain;charset=UTF-8"    }    body = strings.TrimSpace(body)    msg := []byte("To: " + to + "\r\nFrom: " + user + "<" + user + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)    send_to := strings.Split(to, ";")    err := smtp.SendMail(host, auth, user, send_to, msg)    if err != nil {        fmt.Println(err.Error())    }    return err}func readLine2Array(filename string) ([]string, error) {    result := make([]string, 0)    file, err := os.Open(filename)    if err != nil {        return result, errors.New("Open file failed.")    }    defer file.Close()    bf := bufio.NewReader(file)    for {        line, isPrefix, err1 := bf.ReadLine()        if err1 != nil {            if err1 != io.EOF {                return result, errors.New("ReadLine no finish")            }            break        }        if isPrefix {            return result, errors.New("Line is too long")        }        str := string(line)        result = append(result, str)    }    return result, nil}func DelArrayVar(arr []string, str string) []string {    str = strings.TrimSpace(str)    for i, v := range arr {        v = strings.TrimSpace(v)        if v == str {            if i == len(arr) {                return arr[0 : i-1]            }            if i == 0 {                return arr[1:len(arr)]            }            a1 := arr[0:i]            a2 := arr[i+1 : len(arr)]            return append(a1, a2...)        }    }    return arr}func LoadData() {    fmt.Println("LoadData")    file, err := os.Open("data.dat")    defer file.Close()    if err != nil {        fmt.Println(err.Error())        SJ.Name = "使用者名稱"        SJ.Pwd = "使用者密碼"        SJ.Host = "SMTP伺服器:連接埠"        SJ.Subject = "郵件主題"        SJ.Body = "郵件內容"        SJ.Send = "要發送的郵箱,每行一個"        return    }    dec := gob.NewDecoder(file)    err2 := dec.Decode(&SJ)    if err2 != nil {        fmt.Println(err2.Error())        SJ.Name = "使用者名稱"        SJ.Pwd = "使用者密碼"        SJ.Host = "SMTP伺服器:連接埠"        SJ.Subject = "郵件主題"        SJ.Body = "郵件內容"        SJ.Send = "要發送的郵箱,每行一個"    }}func SaveData() {    fmt.Println("SaveData")    file, err := os.Create("data.dat")    defer file.Close()    if err != nil {        fmt.Println(err)    }    enc := gob.NewEncoder(file)    err2 := enc.Encode(SJ)    if err2 != nil {        fmt.Println(err2)    }}var SJ ShuJuvar runing boolvar chEnd chan boolfunc main() {    LoadData()    chEnd = make(chan bool)    var emails, body, msgbox *walk.TextEdit    var user, password, host, subject *walk.LineEdit    var startBtn *walk.PushButton    MainWindow{        Title:   "郵件群發器 By 一曲憂傷",        MinSize: Size{800, 600},        Layout:  HBox{},        Children: []Widget{            TextEdit{AssignTo: &emails, Text: SJ.Send, ToolTipText: "待發送郵件清單,每行一個"},            VSplitter{                Children: []Widget{                    LineEdit{AssignTo: &user, Text: SJ.Name, CueBanner: "請輸入信箱使用者名"},                    LineEdit{AssignTo: &password, Text: SJ.Pwd, PasswordMode: true, CueBanner: "請輸入郵箱登入密碼"},                    LineEdit{AssignTo: &host, Text: SJ.Host, CueBanner: "SMTP伺服器:連接埠"},                    LineEdit{AssignTo: &subject, Text: SJ.Subject, CueBanner: "請輸入郵件主題……"},                    TextEdit{AssignTo: &body, Text: SJ.Body, ToolTipText: "請輸入郵件內容", ColumnSpan: 2},                    TextEdit{AssignTo: &msgbox, ReadOnly: true},                    PushButton{                        AssignTo: &startBtn,                        Text:     "開始群發",                        OnClicked: func() {                            SJ.Name = user.Text()                            SJ.Pwd = password.Text()                            SJ.Host = host.Text()                            SJ.Subject = subject.Text()                            SJ.Body = body.Text()                            SJ.Send = emails.Text()                            SaveData()                            if runing == false {                                runing = true                                startBtn.SetText("停止發送")                                go sendThread(msgbox, emails)                            } else {                                runing = false                                startBtn.SetText("開始群發")                            }                        },                    },                },            },        },    }.Run()}func sendThread(msgbox, es *walk.TextEdit) {    sendTo := strings.Split(SJ.Send, "\r\n")    susscess := 0    count := len(sendTo)    for index, to := range sendTo {        if runing == false {            break        }        msgbox.SetText("發送到" + to + "..." + strconv.Itoa((index/count)*100) + "%")        err := SendMail(SJ.Name, SJ.Pwd, SJ.Host, to, SJ.Subject, SJ.Body, "html")        if err != nil {            msgbox.AppendText("\r\n失敗:" + err.Error() + "\r\n")            if err.Error() == "550 Mailbox not found or access denied" {                SJ.Send = strings.Join(DelArrayVar(strings.Split(SJ.Send, "\r\n"), to), "\r\n")                es.SetText(SJ.Send)            }            time.Sleep(1 * time.Second)            continue        } else {            susscess++            msgbox.AppendText("\r\n發送成功!")            SJ.Send = strings.Join(DelArrayVar(strings.Split(SJ.Send, "\r\n"), to), "\r\n")            es.SetText(SJ.Send)        }        time.Sleep(1 * time.Second)    }    SaveData()    msgbox.AppendText("停止發送!成功 " + strconv.Itoa(susscess) + " 條\r\n")}

然後是walk程式所用的main.manifest,完全照抄官方的,還沒研究其中意思:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>    <dependency>        <dependentAssembly>            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>        </dependentAssembly>    </dependency></assembly>

通過這個main.manifest執行(如果walk安裝好了,應該就有這個命令):

rsrc -manifest main.manifest -o rsrc.syso

是rsrc命令的參數列表,比如我為自已的程式加個ico表徵圖:

rsrc -manifest main.manifest –ico icon.ico -o rsrc.syso

總結:只要熟悉這些非常強大的第三方庫,Go應該也可以做出非常不錯的圖形應用程式,對於接觸C、C++過晚的朋友來說非常合適。


=====================國際慣例=======================

剛開始學著寫一些部落格,寫得不好的地方請見諒,覺得學到了的就賞臉關注下吧~

我的QQ群(PHP)336533596,QQ 451309839,歡迎加入。相互交流,聊天吹牛~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.