如何在Qt中以编程方式绘制一条水平线

39

我正在尝试弄清楚如何在Qt中创建一条水平线。在Designer中很容易创建,但我想以编程方式创建。我已经搜索了一些资料并查看了UI文件中的XML,但仍然无法找到答案。

以下是UI文件中的XML内容:

  <widget class="Line" name="line">
   <property name="geometry">
    <rect>
     <x>150</x>
     <y>110</y>
     <width>118</width>
     <height>3</height>
    </rect>
   </property>
   <property name="orientation">
    <enum>Qt::Horizontal</enum>
   </property>
  </widget>
4个回答

45

水平或垂直线条只是一些属性设置好的 QFrame。在 C++ 中,生成创建线条的代码如下:

line = new QFrame(w);
line->setObjectName(QString::fromUtf8("line"));
line->setGeometry(QRect(320, 150, 118, 3));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);

1
“setGeometry”和“setFrameShadow”是否真的必要?我对Qt还是比较新手,但我希望框架阴影的样式默认情况下应该取决于整个Qt UI风格。我在这里尝试编写跨平台应用程序。 - Michael Scheper
2
@MichaelScheper 不,唯一需要调用的是 setFrameShape()setFrameShadow() - Michael Leonard

37

这里是使用 PySide 的另一种解决方案:

from PySide.QtGui import QFrame


class QHLine(QFrame):
    def __init__(self):
        super(QHLine, self).__init__()
        self.setFrameShape(QFrame.HLine)
        self.setFrameShadow(QFrame.Sunken)


class QVLine(QFrame):
    def __init__(self):
        super(QVLine, self).__init__()
        self.setFrameShape(QFrame.VLine)
        self.setFrameShadow(QFrame.Sunken)

然后可以将其用作(例如):

from PySide.QtGui import QApplication, QWidget, QGridLayout, QLabel, QComboBox


if __name__ == "__main__":
    app = QApplication([])
    widget = QWidget()
    layout = QGridLayout()

    layout.addWidget(QLabel("Test 1"), 0, 0, 1, 1)
    layout.addWidget(QComboBox(), 0, 1, 1, 1)
    layout.addWidget(QHLine(), 1, 0, 1, 2)
    layout.addWidget(QLabel("Test 2"), 2, 0, 1, 1)
    layout.addWidget(QComboBox(), 2, 1, 1, 1)

    widget.setLayout(layout)
    widget.show()
    app.exec_()

导致结果如下:

Windows 10上QHLine的示例


对于未来的读者,PySide仅与Python 3.6或3.6兼容。尝试安装PySide2、4、5、6。 - ElSheikh

9

这里是一个使用标准PyQt5的解决方案,我从shoosh的答案中得出:

from PyQt5 import QtWidgets

class QHSeparationLine(QtWidgets.QFrame):
  '''
  a horizontal separation line\n
  '''
  def __init__(self):
    super().__init__()
    self.setMinimumWidth(1)
    self.setFixedHeight(20)
    self.setFrameShape(QtWidgets.QFrame.HLine)
    self.setFrameShadow(QtWidgets.QFrame.Sunken)
    self.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
    return

class QVSeparationLine(QtWidgets.QFrame):
  '''
  a vertical separation line\n
  '''
  def __init__(self):
    super().__init__()
    self.setFixedWidth(20)
    self.setMinimumHeight(1)
    self.setFrameShape(QtWidgets.QFrame.VLine)
    self.setFrameShadow(QtWidgets.QFrame.Sunken)
    self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
    return

如果你想将它添加到网格中:

separator_vertical = separation_lines.QVSeparationLine()
separator_horizontal = separation_lines.QHSeparationLine()

grid = QtWidgets.QGridLayout()

grid.addWidget(your_widget_left_from_vertical_separator, 0, 0, 1, 1,)
grid.addWidget(separator_vertical, 0, 1, 1, 1)
grid.addWidget(your_widget_right_from_vertical_separator, 0, 2, 1, 1,)
grid.addWidget(separator_horizontal, 1, 0, 1, 2)
grid.addWidget(your_widget_below_horizontal_spacer, 2, 0, 1, 2)

请确保在分隔符上不要使用对齐方式,否则可能会导致它们无法按比例缩放问题。

为了展示所有内容,以下是将其添加到窗口的方法:

import sys
if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    widget = QtWidgets.QWidget()
    widget.setLayout(grid)
    widget.show()
    sys.exit(app.exec())

2
你可以使用这个。
self.line = QFrame()
self.line.setGeometry(QRect(60, 110, 751, 20))
self.line.setFrameShape(QFrame.HLine)
self.line.setFrameShadow(QFrame.Sunken)

self.layout.addWidget(self.line)

1
这与此答案相同:https://dev59.com/Am035IYBdhLWcg3wBLRL#41068447 和 https://dev59.com/Am035IYBdhLWcg3wBLRL#61389578。 - eyllanesc
你是指带有C++的那个吗? - Abdo Abdelaziz
我看到前面三个答案都是基于同一个答案(QFrame.HLineQFrame.Sunken)的翻译,但分别用了C++、pyside和pyqt编写。那么你的回答又有什么不同呢? - eyllanesc
他们都创建了类,还有其他人想要用Python找到简单的解决方案。无论如何,我对C++语言不感兴趣,当我看到关于它的帖子时,我根本不会阅读或理解它们,而且我也没有看到你的帖子。请停止这种评论,让人们学习,我们不是在上课。 - Abdo Abdelaziz
在我看来,这没有什么新意。对我而言,这只是一个简单的复制,没有贡献任何有趣的东西,所以我给了我的 DV。例如,您可以创建一个返回具有这些属性的 QFrame 的函数,但它仍然是一个副本。基础是相同的。 - eyllanesc
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接