Golang中QT-Widgets的QFileDialog问题:定义了6个参数,但需要7个?
Golang中QT-Widgets的QFileDialog问题:定义了6个参数,但需要7个? 各位Gopher们,
这对我来说真是个谜。我正在使用 github.com/therecipe/qt-Package 包,并将一个按钮与匿名函数连接起来,用于选择文件或目录并将所选路径设置到 QLineEdit 中。它确实可以这样工作:
import (
"github.com/therecipe/qt/core"
"github.com/therecipe/qt/uitools"
"github.com/therecipe/qt/widgets"
)
//...
var (
ui_formConfigs map[string](*widgets.QLineEdit)
ui_pushButtons map[string](*widgets.QPushButton)
)
ui_formConfigs = make(map[string]*widgets.QLineEdit)
ui_pushButtons = make(map[string]*widgets.QPushButton)
//...
ui_formConfigs["InputDirectory"] = widgets.NewQLineEditFromPointer(widget.FindChild("inputDirectoryLineEdit", core.Qt__FindChildrenRecursively).Pointer())
ui_formConfigs["InputDirectory"].SetText(config.Paths.InputDirectory)
ui_pushButtons["pushButtonSelectInputDirectory"] = widgets.NewQPushButtonFromPointer(widget.FindChild("pushButtonSelectInputDirectory", core.Qt__FindChildrenRecursively).Pointer())
ui_pushButtons["pushButtonSelectInputDirectory"].ConnectClicked(func(checked bool) {
//ui_formConfigs["InputDirectory"].SetText((*widgets.QFileDialog).GetOpenFileName(nil, "Some title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly))
ui_formConfigs["InputDirectory"].SetText((*widgets.QFileDialog).GetOpenFileName(nil, nil, "Some title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly))
})
然而,
(*widgets.QFileDialog).GetOpenFileName(nil, nil, "Some Title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly)
对我来说很奇怪。因为编译器之前提示我:
方法表达式 widgets.(*QFileDialog).GetOpenFileName 的调用参数不足 已有 (nil, string, string, string, string, widgets.QFileDialog__Option) 需要 (*widgets.QFileDialog, widgets.QWidget_ITF, string, string, string, string, widgets.QFileDialog__Option)
现在请看看 src/github.com/therecipe/qt/widgets/widgets.go 中的定义:
func (ptr *QFileDialog) GetOpenFileName(parent QWidget_ITF, caption string, dir string, filter string, selectedFilter string, options QFileDialog__Option) string {...}
我数了6个参数,但编译器需要7个!!!哪里出错了?这怎么可能呢?
提前感谢!
更多关于Golang中QT-Widgets的QFileDialog问题:定义了6个参数,但需要7个?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
做得好 😊
更多关于Golang中QT-Widgets的QFileDialog问题:定义了6个参数,但需要7个?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我已经解决了这个问题。我之前忽略了(*widgets.QFileDialog).GetOpenFileName实际上是一种没有定义对象的静态方法!因此,需要将对象作为额外的(第一个)参数来调用。
顺便提一下,还有一个可行的替代方案:
ui_formConfigs["InputDirectory"].SetText(widgets.QFileDialog_GetOpenFileName(nil, "Some Title", "", "", "", widgets.QFileDialog__ShowDirsOnly))
非常感谢您的评论!几年前,我开始开发一个跨平台GUI应用程序,在分析了所有可能性后,我也认为使用Qt是开发面向Linux、Windows和macOS应用程序的最佳方式。当时没有其他方案能与之媲美。我需要使用高效的编译语言进行编程,因为这是一个实时音频程序,需要尽可能高的CPU性能。
我希望将来能用Go重写我的项目并继续开发,很高兴知道有一个可用的Go语言Qt绑定!未来,我期待看到Go被应用于更多类型的编程场景中。
哦,对了!我记得之前在Go语言规范中读到过类似的内容。看看这个:
https://golang.org/ref/spec#Method_expressions
你居然在实际开发中遇到了这种情况,这真的很有趣,而且恭喜你找到了解决方案!在将Go与像Qt这样复杂的C++库绑定的代码中发现一些奇怪的东西是很合理的。
我一直对使用Go编写原生GUI应用的想法很感兴趣,用Qt来提供跨平台GUI支持。你觉得therecipe/qt这个包用起来怎么样?你认为它足够成熟可以用于生产环境吗?它是否能够良好运行,满足你的所有需求……而且没有问题?
我真的很想听听任何在Go中成功编写Qt应用的人的意见!
谢谢 😊 我之前不知道这种静态方法调用是有效的!对于有同样疑问的人,以下示例可能会有帮助:
package main
import "fmt"
type myStructType struct {
X int
}
func (s myStructType) doSomething(v int) {
fmt.Println("I got", v)
s.X = v //X ist actually not needed
}
func (s *myStructType) setValue(v int) {
fmt.Println("I set", v)
s.X = v
}
func (s *myStructType) getValue() int {
return s.X
}
func main() {
var a myStructType = myStructType{123}
//Static method call, the first *additional* argument is the object!
fmt.Println("I read", (*myStructType).getValue(&a)) // 123
myStructType.doSomething(a, 1) // 1
(*myStructType).setValue(&a, 2) // 2
fmt.Println("I read", (*myStructType).getValue(&a)) // 2
}
我一直对使用Go编写原生GUI应用的想法很感兴趣,通过Qt提供跨平台GUI支持。请问
therecipe/qt包对您来说效果如何?在您看来,它是否已经足够成熟可用于生产环境?它是否能够良好运行并满足您的所有需求……且没有出现问题?
……嗯,我现在决定将QT投入生产使用。最初我用go-QT、go-GTK和go-GTK3做了一些小实验。过去我喜欢在Python中使用WxWidgets和GTK,对QT不太感冒。对我来说QT过于庞大,而我很喜欢Glade和wxGlade构建器。但现在我需要编写几个工艺可视化界面,这些界面必须能在Win7 😪和Win10 🤕上运行,同时也要支持Linux 😍。
目前看来,QT似乎是唯一足够成熟的GUI框架,能够在多系统上运行且无需大量配置!遗憾的是go-GTK还不够成熟,在Windows下问题更多。但我不得不承认,用QT进行交叉编译确实让我有些头疼。在Win7_32位系统上直接编译go-QT也遇到了许多尚未解决的问题。在Linux下使用Docker开发应用程序似乎是最便捷的方式,但最终要部署到各种Windows系统上。至少我现在有信心,相关问题总能找到解决办法。
另一种替代方案是使用JavaScript-jQuery-EasyUI等框架设计界面,就像现在大家普遍做的那样。但我不喜欢通过消耗大量内存和引入无数依赖来弥补性能缺陷。
QT有一个显著优点:实践证明,将Qt Widgets 5.11的代码示例移植到Go非常实用,这也间接说明其文档质量很高。此外,您还应该关注GitHub - therecipe/examples: Examples for https://github.com/therecipe/qt。
顺便提一下,Home · tomarus/go-gui-libs Wiki · GitHub提供了当前Go语言可实现的可视化技术的精彩概览!
在Go语言中使用therecipe/qt包时,QFileDialog.GetOpenFileName方法确实需要7个参数,这与您看到的函数签名一致。问题在于您使用了方法表达式的调用方式,这需要将接收者作为第一个参数传递。
让我们分析一下正确的调用方式:
问题分析
从错误信息可以看出:
- 方法表达式需要:
(*widgets.QFileDialog, widgets.QWidget_ITF, string, string, string, string, widgets.QFileDialog__Option) - 您提供了:
(nil, string, string, string, string, widgets.QFileDialog__Option)
正确的调用方式
方式1:使用包级函数(推荐)
ui_pushButtons["pushButtonSelectInputDirectory"].ConnectClicked(func(checked bool) {
fileName := widgets.QFileDialog_GetOpenFileName(nil, "Some Title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly)
ui_formConfigs["InputDirectory"].SetText(fileName)
})
方式2:创建QFileDialog实例
ui_pushButtons["pushButtonSelectInputDirectory"].ConnectClicked(func(checked bool) {
fileDialog := widgets.NewQFileDialog(nil, 0)
fileName := fileDialog.GetOpenFileName(nil, "Some Title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly)
ui_formConfigs["InputDirectory"].SetText(fileName)
})
方式3:使用方法表达式(需要接收者)
ui_pushButtons["pushButtonSelectInputDirectory"].ConnectClicked(func(checked bool) {
fileDialog := widgets.NewQFileDialog(nil, 0)
// 方法表达式调用 - 需要接收者作为第一个参数
fileName := (*widgets.QFileDialog).GetOpenFileName(fileDialog, nil, "Some Title", "./", "*", "*", widgets.QFileDialog__ShowDirsOnly)
ui_formConfigs["InputDirectory"].SetText(fileName)
})
完整的工作示例
package main
import (
"github.com/therecipe/qt/core"
"github.com/therecipe/qt/widgets"
)
func main() {
app := widgets.NewQApplication(len(os.Args), os.Args)
window := widgets.NewQMainWindow(nil, 0)
centralWidget := widgets.NewQWidget(nil, 0)
layout := widgets.NewQVBoxLayout()
lineEdit := widgets.NewQLineEdit(nil)
button := widgets.NewQPushButton2("Select Directory", nil)
layout.AddWidget(lineEdit, 0, 0)
layout.AddWidget(button, 0, 0)
centralWidget.SetLayout(layout)
window.SetCentralWidget(centralWidget)
button.ConnectClicked(func(checked bool) {
// 使用包级函数 - 最简洁的方式
selectedDir := widgets.QFileDialog_GetOpenFileName(
nil, // parent
"Select Input Directory", // caption
"./", // dir
"All Files (*)", // filter
"", // selectedFilter
widgets.QFileDialog__ShowDirsOnly, // options
)
lineEdit.SetText(selectedDir)
})
window.Show()
app.Exec()
}
参数说明
GetOpenFileName的7个参数分别是:
parent QWidget_ITF- 父窗口(可为nil)caption string- 对话框标题dir string- 初始目录filter string- 文件过滤器selectedFilter string- 选中的过滤器options QFileDialog__Option- 选项标志- 返回
string- 选择的文件路径
推荐使用widgets.QFileDialog_GetOpenFileName这个包级函数,它封装了方法调用,使用起来更简洁。

