我的研究包括:
我正在构建一个当前有两个回调的 linux“启动器”程序。一个简单地启动点击的应用程序,另一个创建一个新的启动器。第一个工作正常 - 第二个非常棘手。我已经做了很多来解决这个问题。
- 在脚本上运行 PyCharm 调试并观察自己的值等以了解更多信息
- 将 NewLauncher 函数移动到 InitUI 方法中。
- 无休止地改变“self”、“centralWidget”和其他对象引用。
- 使用 functools 部分。
我得到的错误是“AttributeError:'QWidget'对象没有属性'newLauncher'”
这是代码:(如果它太长,我很抱歉 - 我最近被建议不要编辑太多)。
import sys, os
import subprocess
from functools import partial
from PyQt5.QtWidgets import QFileDialog, QToolButton, QHBoxLayout, QGridLayout, QSizePolicy, QSpacerItem, QWidget, QPushButton, QFormLayout, QLineEdit, QAction, QApplication, QDesktopWidget, QMainWindow, QTabWidget, QVBoxLayout
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize
from ruamel.yaml import YAML
yaml = YAML()
file_object = open("/home/tsc/PycharmProjects/launcher/Matrix.yaml", "r")
code = file_object.read()
matrix = yaml.load(code)
file_object.close()
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.initUI()
def launch(self, filepath):
subprocess.run(filepath)
def newLauncher(self):
num_butts = len(matrix)
btn_str = 'btn' + str(num_butts)
file_object = open("/home/tsc/PycharmProjects/launcher/Matrix.yaml", "a")
btn_str = 'btn' + str(num_butts + 1)
file_object.write("\n" + btn_str + ":\n")
self.setStyleSheet('padding: 3px; background: white');
fname, _ = QFileDialog.getOpenFileName(self, "select an executable or document to launch:", "",
"all files (*.*)")
path = fname
fname = os.path.basename(fname)
file_object.write(" " + "name: " + str(fname) + "\n" + " " + "path: " + str(path) + "\n")
self.setStyleSheet('padding: 3px; background: white');
icon, _ = QFileDialog.getOpenFileName(self, "select an image file for the icon:", "",
"all files (*.*)")
file_object.write(" " + "icon: " + str(icon) + "\n")
file_object.close()
def initUI(self):
super(App, self).__init__()
centralWidget = QWidget()
tabWidget = QTabWidget()
lay = QVBoxLayout(centralWidget)
for i in range(3):
page = QWidget()
pagelay = QGridLayout(page)
bmatrix = {}
for btn in matrix:
name = matrix[btn]['name']
filepath = matrix[btn]['path']
icon = matrix[btn]['icon']
bmatrix[btn] = QToolButton(page)
bmatrix[btn].setIcon(QIcon(icon))
bmatrix[btn].setIconSize(QSize(64, 64))
bmatrix[btn].resize(100, 100)
bmatrix[btn].clicked.connect(lambda checked, arg=filepath: self.launch(arg))
pagelay.addWidget(bmatrix[btn])
tabWidget.addTab(page, 'tab{}'.format(i))
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('File')
mainMenu.addMenu(fileMenu)
newAction = QAction('&New', centralWidget)
#1 newAction.triggered.connect(lambda checked, arg=matrix: centralWidget.newLauncher(arg)) - shows window.
#2 newAction.triggered.connect(partial(self.NewLauncher, self)) - shows nothing, App has no NewLauncher
fileMenu.addAction(newAction)
editMenu = mainMenu.addMenu('Edit')
lay.addWidget(mainMenu)
lay.addWidget(tabWidget)
centralWidget.setGeometry(100, 100, 1080, 630)
centralWidget.setWindowTitle('LaunchMaster')
qtRectangle = centralWidget.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
centralWidget.move(qtRectangle.topLeft())
centralWidget.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
这是 yaml 配置文件。如果要对其进行测试,则需要自定义路径等。该界面有一个 menuBar 和一个 tabWidget,其中包含本身包含启动器按钮的页面。
Matrix.yaml:下划线的替换空格(缩进为 2 个字符。)。我还不确定这种标记语法,很抱歉给您带来麻烦。
btn1:
name: firefox
path: firefox-esr
icon: /home/tsc/PycharmProjects/launcher/icons/firefox.jpeg
btn2:
name: thunderbird
path: /home/tsc/thunderbird/thunderbird
icon: /home/tsc/PycharmProjects/launcher/icons/thunderbird.jpeg