Qt 尝试将shell命令的实时/实时输出作为字符串数据从函数返回到主函数

Qt 尝试将shell命令的实时/实时输出作为字符串数据从函数返回到主函数,qt,function,go,Qt,Function,Go,不知道如何解释,因为我在GO中使用QT绑定 所以我粘贴了一个迷你版的程序。 我正在尝试从run()函数返回到QT窗口的实时流。。 我尝试了很多方法。。。最后一个有通道(未成功) 将实时输出传递给main()函数以便我的QT插槽可以更新窗口的最佳方式是什么 包干管 import ( "fmt" // "github.com/therecipe/qt/core" "bufio" "github.com/therecipe/qt

不知道如何解释,因为我在GO中使用QT绑定 所以我粘贴了一个迷你版的程序。 我正在尝试从run()函数返回到QT窗口的实时流。。 我尝试了很多方法。。。最后一个有通道(未成功) 将实时输出传递给main()函数以便我的QT插槽可以更新窗口的最佳方式是什么

包干管

import (
        "fmt"
        //      "github.com/therecipe/qt/core"
        "bufio"
        "github.com/therecipe/qt/widgets"
        "os"
        "os/exec"
)

func run(input string) string {

        stream := make(chan string)

        fmt.Printf("You Clicked The Push Button %s\n", input)

        cmdName := "/usr/bin/nikto"
        cmdArgs := []string{"-host", input}

        cmd := exec.Command(cmdName, cmdArgs...)
        cmdReader, err := cmd.StdoutPipe()
        if err != nil {
                fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
                os.Exit(1)
        }

        scanner := bufio.NewScanner(cmdReader)
        go func() {
                for scanner.Scan() {
                        fmt.Printf("%s\n", scanner.Text())
                        stream <- scanner.Text()
                        //stream = fmt.Sprintf("%s\n", scanner.Text())
                }
        }()

        err = cmd.Start()
        if err != nil {
                fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
                os.Exit(1)
        }

        err = cmd.Wait()
        if err != nil {
                fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err)
                os.Exit(1)
        }

        input = <-stream
        return string(input)
        //return go getOutput(scanner)

}

func main() {
        // Create application
        app := widgets.NewQApplication(len(os.Args), os.Args)

        // Create main window
        window := widgets.NewQMainWindow(nil, 0)
        window.SetWindowTitle("nikto front end")
        window.SetMinimumSize2(400, 400)

        // Create layout

        Layout := widgets.NewQVBoxLayout()

        TopLayout := widgets.NewQHBoxLayout()
        //topright := widgets.NewQHBoxLauout()

        RLayout := widgets.NewQVBoxLayout()
        LLayout := widgets.NewQVBoxLayout()

        Layout.AddLayout(TopLayout, 0)
        Layout.AddLayout(RLayout, 1)
        Layout.AddLayout(LLayout, 0)

        //Create main widget
        mainWidget := widgets.NewQWidget(nil, 0)
        mainWidget.SetLayout(Layout)

        // Create left widget
        LQWidget := widgets.NewQWidget(nil, 0)
        LQWidget.SetLayout(LLayout)

        // Create right widget

        RQWidget := widgets.NewQWidget(nil, 0)
        RQWidget.SetLayout(RLayout)

        // Create label
        urlLabel := widgets.NewQLabel(nil, 0)
        urlLabel.SetText("Target: ")
        TopLayout.AddWidget(urlLabel, 0, 0)

        // Create a line edit
        input := widgets.NewQLineEdit(nil)
        input.SetPlaceholderText("Enter target like http://127.0.0.1")
        TopLayout.AddWidget(input, 0, 0)

        // Create checkboxes
        checkBox1 := widgets.NewQCheckBox2("Default", nil)
        //checkBox1.SetWindowTitle("Check Box")
        LLayout.AddWidget(checkBox1, 0, 0)

        checkBox2 := widgets.NewQCheckBox2("SSL mode", nil)
        //checkBox2.SetWindowTitle("Check Box")
        LLayout.AddWidget(checkBox2, 0, 0)

        checkBox3 := widgets.NewQCheckBox2("no 404", nil)
        //checkBox3.SetWindowTitle("Check Box")
        LLayout.AddWidget(checkBox3, 0, 0)

        output := widgets.NewQTextEdit(nil)
        LLayout.AddWidget(output, 0, 0)

        // Create a button and add it to the layout
        button1 := widgets.NewQPushButton2("2. click me", nil)
        Layout.AddWidget(button1, 0, 0)

        button1.ConnectClicked(func(checked bool) {
                output.Append(run(input.Text()))
        })

        // Set main widget as the central widget of the window
        window.SetCentralWidget(mainWidget)

        // Show the window
        window.Show()

        // Execute app
        app.Exec()
}
导入(
“fmt”
//“github.com/therecipe/qt/core”
“布菲奥”
“github.com/therecipe/qt/widgets”
“操作系统”
“os/exec”
)
func运行(输入字符串)字符串{
流:=生成(chan字符串)
fmt.Printf(“您单击了按钮%s\n”,输入)
cmdName:=“/usr/bin/nikto”
cmdArgs:=[]字符串{“-host”,输入}
cmd:=exec.Command(cmdName,cmdArgs…)
cmdReader,错误:=cmd.StdoutPipe()
如果错误!=零{
fmt.Fprintln(os.Stderr,“为Cmd创建StdoutPipe时出错”,err)
操作系统退出(1)
}
扫描程序:=bufio.NewScanner(cmdReader)
go func(){
对于scanner.Scan(){
fmt.Printf(“%s\n”,scanner.Text())

stream您是否需要对
run
的调用是异步的(这需要通道和goroutine)?如果不需要,您可以简单地使用
bytes.Buffer
来捕获命令输出和返回(这就是我们当前的实现所做的):


运行
返回频道,然后在
main
中读取它(不要在
运行
中从频道读取):

主程序包
进口(
“布菲奥”
“fmt”
“os/exec”
)
func main(){
// ...
按钮1.连接已单击(功能(选中布尔){
流:=运行(input.Text())
go func(){
对于行:=范围流{
output.Append(行)
}
}()
})
// ...
}

func运行(主机字符串)嘿!非常感谢。其实我并不介意怎么做。只要它能工作。我已经测试过了,而且似乎没有按照我想要的方式工作,基本上shell命令有一个常量stdout,到目前为止,我只会在完成后一次获得所有输出。我需要的是在小部件上显示输出,因为它显示为picure a tail-f/var/只记录/消息这是一个命令,并最终完成运行,当然不是一个文件:)这样在shell上使用popen和类似的系统调用很容易,这里的问题是函数和小部件。我认为最好使用qt来呈现此功能,因为它本质上是一种UI行为。要从
run
,你必须确保
输出。Append
可以处理字节流,我不这么认为。嘿,谢谢你的帮助,Peter的另一个建议正是我所需要的。问题是我认为QT go libs仍然缺少QProcess,这是运行系统命令的地方。我几天前打开了一个问题o但没有回应,所以只走了纯围棋路线。你这个人!就像一个魔咒一样工作。我必须注释你的cmd指针,并添加回我的cmd,cmd:=exec.Command(cmdName,cmdArgs…)和你没有包含的其他内容,现在它显示了。我喜欢围棋频道!这有助于我练习。
func run(input string) string {
    cmdName := "/usr/bin/nikto"
    cmdArgs := []string{"-host", input}

    cmd := exec.Command(cmdName, cmdArgs...)
    var b bytes.Buffer
    cmd.Stdout = &b

    err := cmd.Run()
    if err != nil {
        log.Fatal(err)
    }

    return b.String()
}
package main

import (
    "bufio"
    "fmt"
    "os/exec"
)

func main() {
    // ...

    button1.ConnectClicked(func(checked bool) {
            stream := run(input.Text())
            go func() {
                    for line := range stream {
                            output.Append(line)
                    }
            }()
    })

    // ...
}

func run(host string) <-chan string {

    var cmd *exec.Cmd
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
            // ...
    }

    scanner := bufio.NewScanner(cmdReader)
    stream := make(chan string)

    go func() {
            defer close(stream)

            for scanner.Scan() {
                    fmt.Printf("%s\n", scanner.Text())
                    stream <- scanner.Text()
            }
    }()

    go func() {
            if err := cmd.Run(); err != nil {
                    // ...
            }
    }()

    return stream
}