simulating mouse click in menu bar and toolbar using Qtbot - python-3.x

I'm automation a notepad GUI developed in PYQT5 using PYtestqt. when I try to click the menu bar or toolbar options using qtbot it is not simulating the click
def test_quit(qtbot):
window = MainWindow()
qtbot.add_widget(window)
window.show()
qtbot.wait_for_window_shown(window)
qtbot.mouseClick(window.file_menu, QtCore.Qt.LeftButton)

I was trying to find a way to trigger an action under a menu. Since you most likely want to trigger an action (item under the menu), this may help you as well. Instead of using qtbot, use the window directly and call trigger. So something like this:
def test_quit(qtbot):
window = MainWindow()
qtbot.add_widget(window)
window.show()
qtbot.wait_for_window_shown(window)
window.file_quit_action.trigger()

if you wanna just trigger the click event connected action, you can try this.
In MainWindow class:
# binding action and function
action_open = QAction("Open", self)
action_open.setCheckable(False)
action_open.setObjectName("action_open") # Notice set a object name
action_open.triggered.connect(self.file_open)
In test scripts:
def test_file_open_action(qtbot):
window = MainWindow()
qtbot.add_widget(window)
window.show()
win.findChild(QAction, 'action_open').trigger() # call the method
So you can get the same result after simulate click memubar widget.

Related

Clicked Connect Method Triggger more than once

I've function as a edit_parameters when I changed value on my edit_table. When I open the edit table screen edit_parameters function working.
def edit_parameters(self):
self.ui.edit_table.setEditTriggers(QtWidgets.QTableWidget.CurrentChanged)
oldListValue = []
for i in range(0, 46):
oldListValue.append(self.ui.edit_table.item(i, 1).text())
self.ui.changeButton.clicked.connect(partial(self.write_changed_value_to_device,0,oldListValue))
Than I define changeButton in above function, so I expect when I click this button, write_changed_value_to_device calling once. But when I click the button sometimes this function calling more than once
def on_write_changed_value_to_device(self,changeType,oldListValue = []):
print("changed")
When I click once, I see:
changed
changed
changed
Why this happenning I want to call only once when I click the button.

Get system-default labels from QMessageBox standard buttons

I want to show the text from the 'Yes' and the 'No' button in the informative text of a QMessageBox, but I don't see how I can get these labels from the buttons.
from PyQt5.QtWidgets import *
import sys
app = QApplication(sys.argv)
msgbox = QMessageBox()
msgbox.setStandardButtons(msgbox.Yes | msgbox.No)
info_text = "Click '{yes}' to confirm. Click '{no}' to abort."
msgbox.setInformativeText(info_text)
if msgbox.exec_() == msgbox.Yes:
print("Confirmed")
else:
print("Aborted")
By calling setStandardButtons, the button order and the button labels will be set to the default for the current operating system and the current language setting. How can I obtain these defaults so that I can use them for the slots in the string info_text?
I thought about using the buttons attribute from the QMessageBox object, which is a list of QPushButton objects. I can read the labels from there, but I don't see how I could determine whether the first element in the list is the Yes or the No button.
Okay, I was being stupid: along side the buttons attribute, there is also the button() method, which takes as its argument the button type that I want to retrieve. I can then use text() to get the label. Finally, the hotkey marker & has to be stripped from the label:
info_text = "Click '{yes}' to confirm. Click '{no}' to abort.".format(
yes=msgbox.button(msgbox.Yes).text().replace("&", ""),
no=msgbox.button(msgbox.No).text().replace("&", ""))
msgbox.setInformativeText(info_text)

TKinter button avoid double click

I have a script that enables a Power supply after the user click "ONLY ONE TIME" the "START TEST" button, right after, I disable the button to avoid the "double click, however, I have noticed that "some how" if user perform a "double click" my application launch a second operation.
def starttest():
Button(main, text="START TEST", font=("Tahoma", 21), height=1, width=24,
command=starttest, state=DISABLED).place(x=55,y=40)
PS = serial.Serial('COM1', 9600, timeout=.1)
##my code here ...
Does anyone have an idea what should I do to prevent this happen?
Each time you call starttest() function by pressing the inherent button, a new button widget is created: that is why it looks like you are able to click indefinitely on the falsely "same" button.
You should create that button somewhere else in your program:
...
power_supply_btn = Button(... text="START TEST", command=starttest ...)
power_supply_btn.place(x=55,y=40)
...
Then configure the state of that button in your starttest() callback using the configure() function:
def starttest():
global power_supply_btn
power_supply_btn.configure(state=DISABLED)

tkinter treeview: how to disable widget?

We're building a GUI interface with Python+tkinter.
The problem is when we want to set the view mode of an entity. I need to set the view mode or state of the treeview widget as 'disabled'.
How can we solve it?
Thanks for any support.
UPDATE
self.frmTab01.trvDetailorder.configure(selectmode='none')
I'm looking for a solution in which appart from disable the selection, affect the visualization of the widget just like an entry widget.
nbro is right, you need to change the Treeview style to make it look disabled. In addition, I also deactivated the possibility to open/close items when the Treeview is disabled using binding tricks on the mouse click.
In my example I added an entry so that you can compare the look on the two widgets. If you are using OS X or Windows, you might need to change the theme (style.theme_use("clam") should do) because their default themes are not very customizable.
from tkinter import Tk
from tkinter.ttk import Treeview, Style, Button, Entry
root = Tk()
def toggle_state():
if "disabled" in tree.state():
e.state(("!disabled",))
tree.state(("!disabled",))
# re-enable item opening on click
tree.unbind('<Button-1>')
else:
e.state(("disabled",))
tree.state(("disabled",))
# disable item opening on click
tree.bind('<Button-1>', lambda e: 'break')
style = Style(root)
# get disabled entry colors
disabled_bg = style.lookup("TEntry", "fieldbackground", ("disabled",))
disabled_fg = style.lookup("TEntry", "foreground", ("disabled",))
style.map("Treeview",
fieldbackground=[("disabled", disabled_bg)],
foreground=[("disabled", "gray")],
background=[("disabled", disabled_bg)])
e = Entry()
e.insert(0, "text")
e.pack()
tree = Treeview(root, selectmode='none')
tree.pack()
tree.insert("", 0, iid="1", text='1')
tree.insert("1", 0, iid='11', text='11')
Button(root, text="toggle", command=toggle_state).pack()
root.mainloop()

Tkinter, How to do destroy the button I click in a grid made by a for loop

for x in range(xBtns):
for y in range(yBtns):
btn = Button(board, width=2, height=1)
btn.grid(column=x, row=y)
btn.bind('<Button-3>', btnFunction)
Where btnFunction deletes the button that was right-clicked
The event object that is passed to a bound function contains a reference to the widget that received the event:
def btnFunction(event):
event.widget.destroy()
You can just do:
canvas.delete("all")
when the button is clicked.

Resources