I have a function call on button click which is used to display a number of cuboids. However i want the ability to rotate my frame on user mouse drag so as to get the desired viewing angle (as preferred by user)
However, i cant seem to rotate as well as zoom on my display window.
Edit: What i found was upon a right click drag it changes the viewing angle. However it does not get reflected. Weirdly enoughn it is reflected only after i maximize and then restore the screen. Is there some setting i can do to make it work seamlessly.
Also, the first display happens after i move the window from its initial position. Else its just blank upon launch!! Please advise
def testDraw():
global containers
myscene = display(title='Diagram')
#myscene.material = materials.wood
myscene.select()
myscene.exit=False
#myscene.userspin = True
myscene.userspin = 1
myscene.forward = (.1, -.3, -1)
mybox = [['','','','','','','',''] for x in range(len(containers))]
for x in range(len(containers)):
for y in range(len(containers[x])):
mybox[x]=box(pos=(float(containers[x][1])+float(containers[x][2])/2,float(containers[x][3])+float(containers[x][4])/2,float(containers[x][5])+float(containers[x][6])/2),width=float(containers[x][6]),height=float(containers[x][4]),length=float(containers[x][2]))
#,color='color.'+containers[x][7]
#mybox = box(pos=(2.5,1,5), length=10, height=2, width=5,color=color.blue)
#mybox2 = box(pos=(12.5,1,5), length=10, height=2, width=5,color=color.green)
#Name,length0,length1,height0,height1,width0,width1,color
containers=[['Container_1','`enter code here`0','2','0','7','0','2','blue'],
['Container_2','2','5','0','10','0','2','green'],
['Container_3','7','10','0','5','0','2','red']]
I don't understand what is meant by "it does not get reflected". What is "it"? Also, you haven't provided a runnable program, so it' difficult to know what the context is.
I'll advertise that a better place to pose VPython questions is in the VPython forum at
https://groups.google.com/forum/?fromgroups&hl=en#!forum/vpython-users
Related
I'm making a clone of windows 98's start menu. I have the program almost finished I just need to get the buttons to open some programs. However for some reason the windows98 lookalike start menu keeps forcing me to start from the beginning in order to get through the menus. Each "tab" it's a docked borderless window because i was not sure how to make the program the shape it needed to be to appear over the operating system and over any open programs like how the old start menu should be. when i made it all one program it sat in the background when opened or it sat on top of the enter operating system making it really unrealistic. Start menu was only able to be placed on top as submenus when each window was created and destroyed using onenter and on exit when hovering over labels. so each tab is filled with labels that when the mouse hovers over it trades the image for the blue one and if it is a label that has a submenu like for example the programs part of the first start window it opens the next label (or in tkinter's world a new window)
as you can see in the video below the on hover events do not stay once the mouse leaves the window
(I created a transparent window in the background so that when the user clicks out of the start menu the program is aware of it and can handle closing the entire program to look like the start menu is just being closed)
the labels also do not turn blue when trying to backtrack to the previous window.
I am wishing for any kind soul here to assist me in solving these mysteries.
Here is a video showing the issue
https://youtu.be/KeK_qfV_X6s
I want to post the code for the program but the editor says that it is using too many characters to post it here.
I will send an example of how the new tabs are created and hope it's enough. I can send the script itself to someone who needs it.
'''code'''
def createProgramsTab():
global ProgramsTabWindow
ProgramsTabWindow = Toplevel(ClickToExitBackground)
ProgramsTabWindow.geometry("+205+270")
ProgramsTabWindow.geometry("150x147")
ProgramsTabWindow.configure(bg='#c0c0c0')
ProgramsTabWindow.deiconify()
EmptyProgramsTabLabelImage = ImageTk.PhotoImage(Image.open(r'assets/StartMenuPrograms.png'))
EmptyProgramsTabLabel = Label(ProgramsTabWindow, image=EmptyProgramsTabLabelImage)
EmptyProgramsTabLabel.photo = EmptyProgramsTabLabelImage
EmptyProgramsTabLabel.place(x=0,y=0)
HomeBaseaccessoriesButtonImage = ImageTk.PhotoImage(Image.open(r'assets/startaccessoriesdefault.png'))
HomeBaseaccessoriesButton = Button(ProgramsTabWindow, image=HomeBaseaccessoriesButtonImage, borderwidth=-10, highlightthickness=-10, relief=FLAT,bd=-10,bg="#c0c0c0")
HomeBaseaccessoriesButton.photo = HomeBaseaccessoriesButtonImage
HomeBaseaccessoriesButton.place(x=3,y=3, bordermode=INSIDE)
HomeBaseProgramsButtonImage = ImageTk.PhotoImage(Image.open(r'assets/startprogramsdefault.png'))
HomeBaseProgramsButton = Button(HomeBaseWindow, image=HomeBaseProgramsButtonImage, borderwidth=-10, highlightthickness=-10, relief=FLAT,bd=-10,bg="#c0c0c0")
HomeBaseProgramsButton.photo = HomeBaseProgramsButtonImage
HomeBaseProgramsButton.place(x=25,y=44, bordermode=INSIDE)
def onEnterPrograms(event):
global HomeBaseProgramsButtonImage
HomeBaseProgramsButtonImage = ImageTk.PhotoImage(Image.open(r'assets/startprogramsblue.png'))
HomeBaseProgramsButton.config(image=HomeBaseProgramsButtonImage)
HomeBaseProgramsButton.photo = HomeBaseProgramsButtonImage
createProgramsTab()
destroyfavoritesTab()
destroysettingsTab()
destroyaccessoriesTab()
destroydevotionalservicesTab()
destroyinitiationTabWindow()
destroydocumentsTab()
def onLeavePrograms(event):
global HomeBaseProgramsButtonImage
HomeBaseProgramsButtonImage = ImageTk.PhotoImage(Image.open(r'assets/startprogramsdefault.png'))
HomeBaseProgramsButton.config(image=HomeBaseProgramsButtonImage)
HomeBaseProgramsButton.photo = HomeBaseProgramsButtonImage
HomeBaseProgramsButton.bind('<Enter>', onEnterPrograms)
HomeBaseProgramsButton.bind('<Leave>', onLeavePrograms)
HomeBaseWindow.attributes('-type', 'dock')
HomeBaseWindow.wait_visibility(HomeBaseWindow)
HomeBaseWindow.wm_attributes('-alpha', 1.0)
'''code'''
thank you again for any help
Billie
I'm fairly new to programming, so appoloigise for any inconsistencies / using code incorrectly)
I've seen a few similar questions and answers on this topic, however I feel like I may be missing something.
I've drawn a net of a Rubiks Cube, and I want the user to be able to click on an individual 'cubie' to change its colour, so it will filter through the 6 colours.
Basically, what I'm trying to figure out is how to access the tag of the rectangle, from the tag_bind method.
Here is a simplified version of the code I have used:
def clicked(event):
print("You clicked " + str(event))
print(event.widget.find_withtag("current"))
green_00 = cubeCanvas.create_rectangle(20, 240, 90, 310, width=0, fill='green', tag="green_00")
cubeCanvas.tag_bind("green_00", "<Button-1>", clicked)
This currently returns:
You clicked <ButtonPress event num=1 x=56 y=299>
(1,)
Whereas ideally I want it to return:
green_00
The aim would then be to use the tag, to identify the rectangle in itemconfig - so that I can change the colour.
Any answer / a better way to approach this problem is greatly appreciated.
Thanks.
Thanks to Atlas435 - I was missing something very small.
current = event.widget.find_withtag("current")[0]
event.widget.itemconfig(current, *option)
Allows you to access and then change the colour of the specific tag.
I'm trying to make a basic python interface for demo purposes and I really want to keep it simple. I have to use two scrollbars side by side. In scrollbarNR1 there are some user numbers and the other one has to be refreshed whenever someone clicks between the users. I tried to solve it with a recursive function by refreshing every 20 milliseconds my scrollbarNR2 but that just doesn't work because it clears my selection. My question is, how can I tell if my scrollbar was clicked and refresh the data just then?
My code is:
import tkinter
F1 = tkinter.Frame()
userScroll = tkinter.Scrollbar(F1)
userList = tkinter.Listbox(F1)
userScroll.pack(side=tkinter.RIGHT, fill=tkinter.Y)
userList.pack(side=tkinter.LEFT, fill=tkinter.Y)
userScroll['command'] = userList.yview
userList['yscrollcommand'] = userScroll.set
//here comes the insertion loop with the datas - irrelevant atm
def userSelect():
selectedUser = userList.get('active')
print(selectedUser)
userScroll.after(20, userSelect)
I am trying to adjust the context menu in a QTextEdit. I have succeeded in getting access to and then displaying the default menu with the following code:
class LinkTextBrowser(QTextBrowser):
def contextMenuEvent(self, event):
menu = self.createStandardContextMenu(event.pos())
# do stuff to menu here
menu.popup(event.globalPos())
However, this does not work for location-sensitive clicks. The case in question is the "Copy Link Location" item in a QTextBrowser's right click menu, which is only enabled if you right click on a link, for obvious reasons. I can't get it to ever be enabled. I suspect I am passing the wrong position to createStandardContextMenu, but I can't figure out the correct position to feed it.
I have tried both event.globalPos() and event.pos(), neither of which work. I also looked at the source code for QTextEdit, but didn't get anywhere. What position is it expecting?
Edit: Update: It appears the problem is the scrolling in the TextBrowser; if I scroll to the top of the window and use event.pos() it behaves. I don't have working code yet, but correcting for the scroll is the solution.
(Specifically, I want to disconnect the signal emitted by the Copy Link Location action and connect it to my own function so I can adjust the URL before copying it to the clipboard, allowing me to make links absolute and so forth before copying, and I have no particular desire to re-write the working bits.)
Here is the working transform of the coordinates:
class LinkTextBrowser(QTextBrowser):
def contextMenuEvent(self, event):
self.link_pos = event.pos()
# correct for scrolling
self.link_pos.setX(self.link_pos.x() + self.horizontalScrollBar().value())
self.link_pos.setY(self.link_pos.y() + self.verticalScrollBar().value())
menu = self.createStandardContextMenu(self.link_pos)
# do stuff to menu
menu.popup(event.globalPos())
Try self.mapToGlobal(event.pos()), it should take into account scroll position.
Maybe you can try something like:
QMenu *menu = new QMenu();
menu->addAction(...);
menu->exec(textEdit->mapToGlobal(pos));
It's C++ but I'm sure that you can easy convert it to python.
I've want to implement a scroll/pan-feature on a QGraphicsView in my (Py)Qt application. It's supposed to work like this: The user presses the middle mouse button, and the view scrolls as the user moves the mouse (this is quite a common feature).
I tried using the scroll() method inherited from QWidget. However, this somehow moves the view instead - scrollbars and all. See picture.
So, given that this is not the way I'm supposed to do this, how should I? Or is it the correct way, but I do something else wrong? The code I use:
def __init__(self):
...
self.ui.imageArea.mousePressEvent=self.evImagePress
self.ui.imageArea.mouseMoveEvent=self.evMouseMove
self.scrollOnMove=False
self.scrollOrigin=[]
...
def evImagePress(self, event):
if event.button() == Qt.LeftButton:
self.evImageLeftClick(event)
if event.button() == Qt.MidButton:
self.scrollOnMove=not self.scrollOnMove
if self.scrollOnMove:
self.scrollOrigin=[event.x(), event.y()]
...
def evMouseMove(self, event):
if self.scrollOnMove:
self.ui.imageArea.scroll(event.x()-self.scrollOrigin[0],
event.y()-self.scrollOrigin[1])
It works as I expect, except for the whole move-the-widget business.
Fails to scroll http://img55.imageshack.us/img55/3222/scrollfail.jpg
My addition to translate() method.
It works great unless you scale the scene. If you do this, you'll notice, that the image is not in sync with your mouse movements. That's when mapToScene() comes to help. You should map your points from mouse events to scene coordinates. Then the mapped difference goes to translate(), voila viola- your scene follows your mouse with a great precision.
For example:
QPointF tmp2 = mapToScene(event->pos());
QPointF tmp = tmp2.mapToScene(previous_point);
translate(tmp.x(),tmp.y());
I haven't done this myself but this is from the QGraphicsView documentation
... When the scene is larger
than the scroll bars' values, you can
choose to use translate() to navigate
the scene instead.
By using scroll you are moving the widget, translate should achieve what you are looking for, moving the contents of the QGraphicsScene underneath the view
Answer given by denis is correct to get translate to work. The comment by PF4Public is also valid: this can screw up scaling. My workaround is different than P4FPublc's -- instead of mapToScene I preserve the anchor and restore it after a translation:
previousAnchor = view.transformationAnchor()
#have to set this for self.translate() to work.
view.setTransformationAnchor(QGraphicsView.NoAnchor)
view.translate(x_diff,y_diff)
#have to reset the anchor or scaling (zoom) stops working:
view.setTransformationAnchor(previousAnchor)
You can set the QGraphicsScene's area that will be displayed by the QGraphicsView with the method QGraphicsView::setSceneRect(). So when you press the button and move the mouse, you can change the center of the displayed part of the scene and achieve your goal.