假设我在 Qt Designer 中创建了一个 ui 文件,我想动态加载它然后操作小部件,例如:
例子.py:
from PyQt5 import QtWidgets, uic
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
uic.loadUi('example.ui', self)
# No code completion here for self.myPushButton:
self.myPushButton.clicked.connect(self.handleButtonClick)
self.show()
Run Code Online (Sandbox Code Playgroud)
在 PyCharm (2017.1.4) 中,是否有标准/方便的方式为以这种方式加载的小部件启用代码完成?
目前我正在使用这个(在加载 ui 文件后在构造函数中编写):
self.myPushButton = self.myPushButton # type: QtWidgets.QPushButton
# Code completion for myPushButton works at this point
Run Code Online (Sandbox Code Playgroud)
我也想到了这一点,但它似乎并没有做到这一点:
assert isinstance(self.myPushButton, QtWidgets.QPushButton)
# PyCharm does not even recognise myPushButton as an attribute of self at this point
Run Code Online (Sandbox Code Playgroud)
最后,我也想到了使用python stubs,比如:
例子.pyi:
class MyWidget(QtWidgets.QWidget):
def __init__(self):
self.myPushButton: QtWidgets.QPushButton …
Run Code Online (Sandbox Code Playgroud) 假设我有一个自定义 PyQt 小部件,我想在 Qt Designer 中使用它,例如用于 matplotlib 画布:
情节小部件.py:
from PyQt5 import QtWidgets
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg, NavigationToolbar2QT
)
class PlotWidget(QtWidgets.QWidget):
def __init__(self, parent=None, toolbar=True, figsize=None, dpi=100):
super(PlotWidget, self).__init__(parent)
self.setupUi(toolbar, figsize, dpi)
def setupUi(self, toolbar=True, figsize=None, dpi=100):
layout = QtWidgets.QVBoxLayout(self)
self.figure = Figure(figsize=figsize, dpi=dpi)
self.canvas = FigureCanvasQTAgg(self.figure)
if toolbar:
self.toolbar = NavigationToolbar2QT(self.canvas, self)
layout.addWidget(self.toolbar, 0)
layout.addWidget(self.canvas, 1)
Run Code Online (Sandbox Code Playgroud)
在 Qt Designer 中,我可以轻松地为此提升 QWidget,将头文件设置为“my_module/plot_widget.h”并将其名称设置为 PlotWidget。然后,我可以通过动态加载 ui 文件来构造一个小部件,如下所示:
示例.py:
from PyQt5 import QtWidgets, uic
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent=None): …
Run Code Online (Sandbox Code Playgroud) 在 PyCharm 中,我通常对这样的变量使用尾随类型提示(不确定调用它们的正确方法):
my_var = my_other_variable # type: MyObject
Run Code Online (Sandbox Code Playgroud)
但是,有时我已经有很长的一行无法真正拆分,或者类型提示有点长,例如:
my_var = my_really_long_variable_name # type: QtWidgets.QVeryLongQtClassName
Run Code Online (Sandbox Code Playgroud)
这将使整行比我的行宽限制(79 个字符)长,因此 PyCharm 会标记警告。
因此,有没有办法将类型提示放在不同的行中?我尝试了这些,但它们似乎不起作用:
# type: QtWidgets.QVeryLongQtClassName
my_var = my_really_long_variable_name
my_var = my_really_long_variable_name \
# type: QtWidgets.QVeryLongQtClassName
Run Code Online (Sandbox Code Playgroud)
我能想到的最接近的是这个,它可能不会真正缩短线宽:
my_var = \
my_really_long_variable_name # type: QtWidgets.QVeryLongQtClassName
Run Code Online (Sandbox Code Playgroud)
否则,我唯一的选择就是做这样的事情:
v = my_really_long_variable_name
my_var = v # type: QtWidgets.QVeryLongQtClassName
Run Code Online (Sandbox Code Playgroud)
根据我所做的测试,缩短类型的另一种选择似乎不起作用;PyCharm 似乎很难识别my_var
's 类型QtWidgets.QVeryLongQtClassName
在这种情况下确实如此:
t = QtWidgets.QVeryLongQtClassName
my_var = my_really_long_variable_name # type: t
Run Code Online (Sandbox Code Playgroud) 我想手动为绘图创建一个图例,它不直接引用绘图中的任何数据,例如:
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
plt.plot([0, 1], [3, 2])
line = Line2D([], [], label='abc', color='red', linewidth=1.5, marker='o',
markerfacecolor='yellow', markeredgewidth=1.5, markersize=16)
plt.legend(handles=[line], numpoints=1)
plt.show()
Run Code Online (Sandbox Code Playgroud)
这很好用,因为我也找不到设置标记边缘样式(即实线、虚线、点线等)的方法。Line2D 没有 markeredgestyle 属性或类似属性,并且设置 linestyle 似乎不会影响标记边缘样式。有什么解决方法吗?
我想到了一些方法,但我不确定它们的可行性:
理想情况下,线条样式和标记边缘样式可能不同,但如果有一种方法可以更改标记边缘样式,涉及覆盖线条样式,我也会采用它。
我正在使用 matplotlib 1.5.3。