Issue
Im creating a workshop manual for my motorbike and my plan is to make the main window show drawn image of the bike (see example below, picture from google) and i would be able to click certain parts of the bike. Lets say i want to see information about the engine, i could click the engine and it would open up.
Should i create an image with transparent background for each part and put them on right spots in the software? If so, how do i make them clickable by "ignoring" the background so only the visible part would be clickable?
Solution
Here's what I got coding up the approach suggested by @ekhumoro
import sys
from PySide2.QtWidgets import QWidget, QVBoxLayout, QApplication, QLabel
from PySide2.QtGui import QPixmap, QPolygon
from PySide2.QtCore import QPoint
from PySide2.QtCore import Qt as Qt
class TextEditDemo(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Motorbike Workshop")
# create the image
self.bike_img = QPixmap("bike.jpg")
self.pixmap_label = QLabel()
self.pixmap_label.setPixmap(self.bike_img)
# connect the mouse press event on the image to the img_click function
self.pixmap_label.mousePressEvent = self.img_click
# create the polygons
first_polygon = QPolygon() << QPoint(0, 0) << QPoint(10, 0) << QPoint(10, 10) << QPoint(0, 10)
second_polygon = QPolygon() << QPoint(20, 20) << QPoint(30, 20) << QPoint(30, 30) << QPoint(20, 30)
# create a dictionary containing the name of the area, the polygon and the function to be called when
# the polygon is clicked
self.clickable_areas = {
"first": {
"polygon": first_polygon,
"func": self.func1
},
"second": {
"polygon": second_polygon,
"func": self.func2
}
}
layout = QVBoxLayout()
layout.addWidget(self.pixmap_label)
self.setLayout(layout)
def img_click(self, event):
# get the position of the click
pos = event.pos()
# iterate over all polygons
for area in self.clickable_areas:
# if the point is inside one of the polygons, call the function associated with that polygon
if self.clickable_areas[area]["polygon"].containsPoint(pos, Qt.FillRule.OddEvenFill):
self.clickable_areas[area]["func"]()
return
self.func3()
# the functions to be called when specific polygons are clicked
def func1(self):
print("first polygon clicked!")
def func2(self):
print("second polygon clicked!")
def func3(self):
print("no polygon was clicked")
def main():
app = QApplication(sys.argv)
win = TextEditDemo()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Explanation:
self.clickable_areas
is dictionary holding all the polygons that can be clicked and their respective funtions. Every time the image is clicked the position where the image was clicked is saved. Then we iterate over every polygon and use containsPoint
to check if the position is inside the polygon. If that is the case the corresponding function to the polygon is called.
For this to work you must manually define all the polygons that are supposed to trigger a function. For that I would recommend using an image editor of your choice to create the polygons and then copy the points over to your code.
Answered By - Mergen Studios
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.