Python 从连接到QML的PyQt5打开文件对话框
我在QML中的Python 从连接到QML的PyQt5打开文件对话框,python,pyqt,pyqt5,qml,Python,Pyqt,Pyqt5,Qml,我在QML中的应用程序窗口中定义了一个按钮(实际上它是一个鼠标earea)。我设法从PyQt5连接到它的clicked事件。现在我试图显示“保存文件”对话框,但出现错误: QWidget: Cannot create a QWidget without QApplication 我的代码如下所示: 从PyQt5.QtCore导入QUrl,QObject#pylint:disable msg=E0611 从PyQt5.QtGui导入qgui应用程序,QIcon#pylint:disable ms
应用程序窗口中定义了一个按钮(实际上它是一个鼠标earea
)。我设法从PyQt5连接到它的clicked事件。现在我试图显示“保存文件”对话框,但出现错误:
QWidget: Cannot create a QWidget without QApplication
我的代码如下所示:
从PyQt5.QtCore导入QUrl,QObject#pylint:disable msg=E0611
从PyQt5.QtGui导入qgui应用程序,QIcon#pylint:disable msg=E0611
从PyQt5.QtQml导入QQmlApplicationEngine#pylint:disable msg=E0611
从PyQt5.QtWidgets导入QFileDialog#pylint:disable msg=E0611
def openFile():
options=QFileDialog.options()
选项|=QFileDialog.DontUsenactiveDialog
filename=QFileDialog.getOpenFileName(无,“QFileDialog.getOpenFileName()”、“”、“所有文件(*);Python文件(*.py)”,选项=选项)
打印(文件名)
def run():
app=qgui应用程序(sys.argv)
app.setWindowIcon(QIcon(资源路径(“资产\\图像\\icon.ico”))
引擎=QQmlApplicationEngine()
engine.load(资源路径(“qml\\Window.qml”))
engine.quit.connect(app.quit)
如果不是engine.rootObjects():
返回-1
button=engine.rootObjects()[0]。findChild(QObject,“openButton”)
按钮。单击。连接(openFile)
return app.exec()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
sys.exit(run())
我还尝试通过ApplicationWindow
而不是None
,但随后出现了一个类型错误:
TypeError: getOpenFileName(parent: QWidget = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0): argument 1 has unexpected type 'QWindow'
我认为这没有多大意义,因为QMainWindow
继承了QWidget
如何从我的openFile()
函数显示对话框
编辑:为了完整起见,这里是我的.qml文件的精简版本
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQuick 2.3
ApplicationWindow {
id: mainWindow
visible: true
width: 600
height: 400
Item {
anchors.top: titleBar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
property bool isMainButtonFocused: false
objectName: "openButton"
signal clicked()
Label {
padding: 5
text: "<b><font color='#fefefe'>Hello World</font></b>"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.family: "Helvetica"
font.pointSize: 9
background: Rectangle {
color: mouseAreaOpenFolderButton.containsMouse ? "#777777" : "#333333"
border.width: isMainButtonFocused ? 2 : 1
border.color: "#ffffff"
radius: 5
}
MouseArea {
id: mouseAreaOpenFolderButton
anchors.fill: parent
hoverEnabled: true
onClicked: {
isMainButtonFocused = true
parent.parent.clicked()
}
}
}
}
}
导入QtQuick.Window 2.2
导入QtQuick.Controls 2.3
导入QtQuick.Layouts 1.3
导入QtQuick 2.3
应用程序窗口{
id:主窗口
可见:正确
宽度:600
身高:400
项目{
锚。顶部:标题栏。底部
anchors.left:parent.left
anchors.right:父项.right
.bottom:parent.bottom
属性bool isMainButtonFocused:false
objectName:“openButton”
点击信号()
标签{
填充:5
文字:“你好,世界”
anchors.verticalCenter:父级.verticalCenter
anchors.horizontalCenter:父级.horizontalCenter
font.family:“Helvetica”
font.pointSize:9
背景:矩形{
颜色:鼠标eaOpenFolderButton.containsMouse?”#777777:“#333333”
边框宽度:isMainButtonFocused?2:1
border.color:“#ffffff”
半径:5
}
鼠耳{
id:mouseAreaOpenFolderButton
锚定。填充:父级
hoverEnabled:true
再次点击:{
isMainButtonFocused=true
parent.parent.clicked()
}
}
}
}
}
错误非常明显:
- 如果要使用QFileDialog之类的QWidget,则必须创建QApplication
- 如果您要将QWidget传递给父对象,就像QFileDialog一样,那么该父对象必须是另一个QWidget,但ApplicationWindow不是QWidget,而是导致该错误的QWindow
# ...
class Helper(QObject):
@pyqtSlot(QUrl)
def read_file(self, url):
filename = url.toLocalFile()
print(filename)
def run():
app = QGuiApplication(sys.argv)
app.setWindowIcon(QIcon(resource_path("assets\\images\\icon.ico")))
engine = QQmlApplicationEngine()
helper = Helper()
engine.rootContext().setContextProperty("helper", helper)
# ...
导入QtQuick.Window 2.2
导入QtQuick.Controls 2.3
导入QtQuick.Layouts 1.3
导入QtQuick 2.3
导入QtQuick.Dialogs 1.3
应用程序窗口{
id:主窗口
可见:正确
宽度:600
身高:400
项目{
锚。顶部:标题栏。底部
anchors.left:parent.left
anchors.right:父项.right
.bottom:parent.bottom
属性bool isMainButtonFocused:false
标签{
填充:5
文字:“你好,世界”
anchors.verticalCenter:父级.verticalCenter
anchors.horizontalCenter:父级.horizontalCenter
font.family:“Helvetica”
font.pointSize:9
背景:矩形{
颜色:鼠标eaOpenFolderButton.containsMouse?”#777777:“#333333”
边框宽度:isMainButtonFocused?2:1
border.color:“#ffffff”
半径:5
}
鼠耳{
id:mouseAreaOpenFolderButton
锚定。填充:父级
hoverEnabled:true
再次点击:{
//isMainButtonFocused=true
fileDialog.visible=true
}
}
}
}
文件对话框{
id:fileDialog
标题:“请选择一个文件”
selectedNameFilter:“所有文件(*);Python文件(*.py)”
不接受:{
helper.read_文件(fileDialog.fileURL[0])
}
}
}
首先,将QML应用程序逻辑从QML中移出是一个非常糟糕的主意。更糟糕的想法是混合使用QtQuick和QWidgets。你为什么不改用它呢?至于问题-错误很明显-您必须使用
QApplication
而不是QGuiApplication
。更多信息请参见讨论。我不想使用FileDialog,因为我想用Python检索结果,因为我需要从那里读出结果。然而我得出的结论是,这将是最简单的方法。。。
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQuick 2.3
import QtQuick.Dialogs 1.3
ApplicationWindow {
id: mainWindow
visible: true
width: 600
height: 400
Item {
anchors.top: titleBar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
property bool isMainButtonFocused: false
Label {
padding: 5
text: "<b><font color='#fefefe'>Hello World</font></b>"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.family: "Helvetica"
font.pointSize: 9
background: Rectangle {
color: mouseAreaOpenFolderButton.containsMouse ? "#777777" : "#333333"
border.width: isMainButtonFocused ? 2 : 1
border.color: "#ffffff"
radius: 5
}
MouseArea {
id: mouseAreaOpenFolderButton
anchors.fill: parent
hoverEnabled: true
onClicked: {
// isMainButtonFocused = true
fileDialog.visible = true
}
}
}
}
FileDialog {
id: fileDialog
title: "Please choose a file"
selectedNameFilter: "All Files (*);;Python Files (*.py)"
onAccepted: {
helper.read_file(fileDialog.fileUrls[0])
}
}
}