小编Fer*_*ndr的帖子

PyCharm / PyQt:如何使用动态加载的 ui 文件获取代码完成

假设我在 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)

python pyqt pycharm

7
推荐指数
1
解决办法
1148
查看次数

PyQt / Qt Designer - 无需插件即可升级小部件的额外参数

假设我有一个自定义 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)

python pyqt qt-designer

5
推荐指数
1
解决办法
2705
查看次数

PyCharm - 尾随类型提示和线宽限制

在 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)

python type-hinting pycharm

5
推荐指数
1
解决办法
736
查看次数

手动图例中的自定义标记边缘样式

我想手动为绘图创建一个图例,它不直接引用绘图中的任何数据,例如:

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 似乎不会影响标记边缘样式。有什么解决方法吗?

我想到了一些方法,但我不确定它们的可行性:

  • 使用与 Line2D 完全不同的东西。它需要在图例中显示,具有与 Line2D 相同的格式选项,以及额外的标记边缘样式。不确定这样的类是否存在
  • 创建一个从 Line2D 派生的自定义类并自己实现该标记边缘样式
  • 在绘图本身中创建数据,然后将其从那里删除,同时以某种方式将其保留在图例中。不确定是否存在允许我在实际图表中执行此操作的类。请注意,它必须同时包含一个标记和一条线。我能想到的最接近的事情是对标记使用散点图,对线条使用绘图,但这会显示两个图例条目(除非有办法将它们组合成一个)

理想情况下,线条样式和标记边缘样式可能不同,但如果有一种方法可以更改标记边缘样式,涉及覆盖线条样式,我也会采用它。

我正在使用 matplotlib 1.5.3。

python matplotlib

3
推荐指数
1
解决办法
3163
查看次数

标签 统计

python ×4

pycharm ×2

pyqt ×2

matplotlib ×1

qt-designer ×1

type-hinting ×1