根据用户输入绘制一条线
Posted
技术标签:
【中文标题】根据用户输入绘制一条线【英文标题】:Drawing a line depending on user input 【发布时间】:2020-02-06 08:32:34 【问题描述】:关于 PyQt5 的使用,我有以下问题: 我在 QtDesigner 和 PyQt5 中创建了一个带有标签的 GUI(这是一个 png - 带有通过蓝线和绿线连接的站点的地图)、一个 textEdit 和一个按钮。
现在,我想在 textEdit 中输入一个介于 1 和 4 之间的数字。根据用户输入,附加图像中的部分蓝线应以红色绘制。
我想一个例子解释得更好:如果TextEdit中的用户输入是2并且点击了pushButton,那么从S1到S3的蓝线应该被绘制成红色。如果TextEdit中的用户输入为1,再次点击pushButton,S1到S2的蓝线会被画成红色,所以S2到S3的红线又会变成蓝色。
mapDrawer.py
from PyQt5 import uic
from PyQt5.QtWidgets import QLabel, QMainWindow, QApplication, QWidget, QVBoxLayout
from PyQt5.QtGui import QPixmap
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__() # Call the inherited classes __init__ method
uic.loadUi('DesignerGUI.ui', self) # Load the .ui file
self.setWindowTitle("GUI for user defined track drawing")
pixmap = QPixmap('mapRail.png')
self.pic_label.setPixmap(pixmap)
self.pic_label.setScaledContents(True)
self.show() # Show the GUI
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
DesignerGUI.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>577</width>
<height>347</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string><html><head/><body><p><span style=" color:#0055ff;">Blue Line</span></p></body></html></string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>11515151</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="pic_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>183</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1460</width>
<height>400</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>577</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
【问题讨论】:
图像总是一样的吗?如果没有,这些图像是如何创建的? 所示示例非常简化。在最终的 GUI 中,我想有几张地图,它们有更多的车站和线路,如示例中所示。未更改的图像/地图提供给用户 - 不是 GUI 的一部分。我的意思是我还可以制作很多图片,涵盖所有可能的用户输入,但这会导致很多图片(大数据量)并且需要大量的手动工作。我只是认为有一种方法可以自动执行此操作。 您的问题可能有几种可能的方法,这完全取决于这些电路的管理或创建方式。如果有一种方法可以访问图形对象(形状、位置、颜色),并且最重要的是,可以参考您需要更改的那些,您可以使用自定义小部件并覆盖paintEvent
自己绘制电路.如果它们是 svg(并且它们的内部结构允许),则您可以打开它们并更改颜色(但这会更棘手)。但如果它们是普通的光栅图像,你别无选择,只能创建它们。
【参考方案1】:
由于您使用 .png 来显示您的网络,因此创建单独的 .png 可能是最简单的,每个选项一个,并相应地更改像素图。例如,考虑以下四个我保存为“squares0.png”到“squares3.png”的图像。
要在按下按钮时更改显示的像素图,您可以执行类似的操作
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__() # Call the inherited classes __init__ method
uic.loadUi('laser.ui', self) # Load the .ui file
self.setWindowTitle("GUI for user defined track drawing")
self.pixmaps = '1':'squares1.png', '2':'squares2.png', '3':'squares3.png'
self.default_pixmap = 'squares0.png'
self.pic_label.setScaledContents(True)
self.pushButton.clicked.connect(self.set_pixmap)
self.set_pixmap()
self.show() # Show the GUI
def set_pixmap(self, strng = ''):
text = self.textEdit.toPlainText().strip()
file = self.pixmaps.get(text, self.default_pixmap)
pixmap = QPixmap(file)
self.pic_label.setPixmap(pixmap)
顺便说一句,为了获得更加用户友好的体验,您可以考虑使用QSpinBox
或QComboBox
而不是QTextEdit
来输入数字。
【讨论】:
非常感谢您提出的解决方案和关于用户友好性的建议。我也在考虑这种解决方案。不幸的是,在考虑大量地图和可能性时,需要进行大量手动工作。但无论如何这会起作用:),也许还有其他方法?以上是关于根据用户输入绘制一条线的主要内容,如果未能解决你的问题,请参考以下文章
如何用CoreGraphics绘制一条线,它的线索将开始以一定的长度消失?