PyQt:如何将我的脚本转换为 GUI?

Posted

技术标签:

【中文标题】PyQt:如何将我的脚本转换为 GUI?【英文标题】:PyQt: How convert my script to GUI? 【发布时间】:2017-10-11 18:26:20 【问题描述】:

我正在关注 this tutorial 的 PyQt5 GUI 窗口:

这是我在 pastebin 上的代码。

import sys
from PyQt5 import QtWidgets, QtGui


def window1():
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
b = QtWidgets.QPushButton('Comparison Report', w)
l1 = QtWidgets.QLabel(w)
l2 = QtWidgets.QLabel(w)
l1.setText('Main Page')
b.setGeometry(200, 100, 300, 70)
w.setWindowTitle('Diff Util')
w.setGeometry(800, 200, 720, 800)
l1.move(310, 5)
w.show()
sys.exit(app.exec_())

#import file_report

#def on_click(self):
#file_report()


window1()

这里也是 pastebin 上的比较文件脚本...但我需要 10rep 来链接它>_>

import sys
import os
import difflib

first_file = input("Select original file: ")
second_file = input("Select second file for comparison: ")

first_file_lines = open(first_file).readlines()
second_file_lines = open(second_file).readlines()

difference = difflib.htmlDiff(tabsize=8, 
wrapcolumn=100).make_file(first_file_lines, second_file_lines, first_file, second_file, charset='utf-8')
difference_report = open('difference_report.html', 'w')
difference_report.write(difference)
difference_report.close()

os.startfile('difference_report.html')

我的问题是,如何将我的 file_report.py 连接到我用 PyQt5 创建的按钮?

如您所见,我注释掉了“import file_report”,因为据我了解,我应该导入我的脚本......但导入会导致它在终端中运行脚本,执行后将打开我的 GUI。我想运行此脚本,但将其包含在我创建的 GUI 窗口中,而不是打开终端执行。

那么我应该在 PyQt5 脚本的哪个位置导入,并包含 .py 文件?

【问题讨论】:

input() 是一个阻塞任务,因此不建议在 GUI 中使用它,作为替换该任务的组件的 GUI,在 PyQt 的情况下是 QLineEdit。 好吧,所以我必须将 input() 方法更改为 PyQt5 可以为自己的用户输入解释的方法?所以这意味着我必须重写我的脚本以包含 PyQt5 元素? 是的,这就是我想要的。 我可以帮助你,但我有一个问题,我不明白 startfile(),Linux 不存在,但如果你告诉我你是做什么的,你可以举个例子 @zero01alpha QtPy 是什么? 【参考方案1】:

GUI 对阻塞任务不友好,因为它们的存在会创建一个循环。因此不应该使用函数input(),使用库提供的元素作为QLineEdit的解决方案,PyQt也提供了选择文件的对话框。

import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import difflib

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.setLayout(QtWidgets.QGridLayout())

        self.le1 = QtWidgets.QLineEdit("", self)
        self.le2 = QtWidgets.QLineEdit("", self)
        self.le3 = QtWidgets.QLineEdit("", self)
        self.btn1 = QtWidgets.QPushButton("Select first file")
        self.btn2 = QtWidgets.QPushButton("Select second file")
        self.btn3 = QtWidgets.QPushButton("Select save File")
        self.btnRun = QtWidgets.QPushButton("Run")

        self.layout().addWidget(self.le1, 1, 1)
        self.layout().addWidget(self.le2, 2, 1)
        self.layout().addWidget(self.le3, 3, 1)
        self.layout().addWidget(self.btn1, 1, 2)
        self.layout().addWidget(self.btn2, 2, 2)
        self.layout().addWidget(self.btn3, 3, 2)
        self.layout().addWidget(self.btnRun, 4, 2)
        self.btnRun.clicked.connect(self.onRun)

        self.btn1.clicked.connect(self.selectFirstFile)
        self.btn2.clicked.connect(self.selectSecondFile)
        self.btn3.clicked.connect(self.selectSaveFile)

    def selectFirstFile(self):
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
        if filename != "":
            self.le1.setText(filename)

    def selectSecondFile(self):
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
        if filename != "":
            self.le2.setText(filename)

    def selectSaveFile(self):
        filename, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
        if filename != "":
            self.le3.setText(filename)


    def onRun(self):
        first_file = self.le1.text()
        second_file = self.le2.text()
        output_file = self.le3.text()

        first_file_lines = open(first_file).readlines()
        second_file_lines = open(second_file).readlines()

        difference = difflib.HtmlDiff(tabsize=8, wrapcolumn=100).make_file(first_file_lines, second_file_lines, first_file, second_file, charset='utf-8')
        difference_report = open(output_file, 'w')
        difference_report.write(difference)
        difference_report.close()
        QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(output_file))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

【讨论】:

这正是我想要做的,但我不明白 PyQt5 想要它如何编写。每次我看到如何import 它的写法都不一样。然后,当我试图把事情写出来时,我最终得到了好坏参半的结果。然后在我的代码 pylint 的某处声称“即使你在上面写了它,你也没有定义这个变量。” :[感谢您的回答,但我正在努力理解这一切。 在python中导入的方式有很多,例如使用QLineEdit可以通过以下方式:from PyQt5 import QtWidgets le = QtWidgets.QLineEdit()或者其他方式:from PyQt5.QtWidgets import QLineEdit le = QLineEdit() 另外,GUI 的动态与我们称之为初始的编程不同。在您的情况下,查看代码的方式是从上到下顺序的,在 gui 中也会发生相同的情况,但它是隐藏的。在 GUI 中,您必须在事件之前执行任务,这可以是单击、修改 GUI 的大小等。然后 GUI 会警告我们这些更改,在 PyQt 的情况下,通过信号和事件来完成,在对于信号的情况,我们必须将它连接到某个插槽,也就是说应用程序在通知信号时会调用该插槽。

以上是关于PyQt:如何将我的脚本转换为 GUI?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 PyQt5 GUI 冻结

如何在pyqt5 ui小部件代码中使用python脚本

PyQt:如何在 Raspberry Pi 桌面启动时运行 GUI?

Pygame和PyQt4如何集成?

从 PyQt4 迁移到 PyQt5 时面临的问题

在 main 上而不是在 pyqt5 的脚本上实现按钮的功能