pyqt6 QMessageBox blocking unittest - python

In a window class I have this button...
encrypt_button = QPushButton("Generate")
encrypt_button.setProperty('class', 'warning')
encrypt_button.clicked.connect(
lambda: encrypt_message(encrypt_message_box.toPlainText(), encrypt_public_key_box.toPlainText(),
encrypt_output_box))
encrypt_button.setObjectName("encrypt_button")
The encrypt_message function opens a error QMessageBox if there are values missing...and all works fine.
But I've come to write a unittest and I cannot seem to test for it opening...when I simulate the button click the window actually opens and will not continue until I click OK
def test_copy(self):
""" checks to make sure the button doesn't copy when its blank """
for button in self.window.copy_buttons:
button.click()
##some test here
I've enlisted the help of our friendly AI helper, who keeps telling me to use QSignalSpy or qWaitForWindowExposed, but everything I try just results in the same thing. The QMessageBox opens and I'm stuck waiting for user input.
Any suggestions?

Related

Handling Context Menu of the taskbar icon with pywinauto

I am trying to automate the exiting operation on one of the apps. The app's icon is located in the taskbar. I was successfull in opening that icon's context menu with the modified code that I have found on stackoverflow:
import pywinauto
from pywinauto.application import Application
import time
app= "Service is enabled."
app = Application(backend="uia").connect(path="explorer.exe")
st = app.window(class_name="Shell_TrayWnd")
t = st.child_window(title="Notification Chevron").wrapper_object()
t.click()
time.sleep(1)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
# time.sleep(1)
appOpened= list_box_win.child_window(title = app)
appOpened.click_input(button = "right")
After the execution of the code above I get to the point when the context menu is opened:
The next thing that I want to do is to click on Exit, I have tried doing it by specifying the mouse click coordinates, but I have noticed that the position of the parent icon is changing from time to time.
What I would like to do is to get the handle on the Exit button and send click automatically.
------Edit-------
The icon is located in the hidden icons
So you want to access to the right click context menu. As said in this answer, you can do something like :
listbox.PopupMenu["Exit"].set_focus().click_input()

How to get custom signals from a Qt dialog box

I have a QDialog with 3 buttons - Apply, OK and Cancel. In the __init__ method of the Dialogbox, I am connecting the OK and Cancel using the following:
buttonBox.accepted.connect( self.accept )
buttonBox.rejected.connect( self.reject )
In my main form, I am able to run a method (addNameToSandbox) for the OK signal using
self.__nameDialog.accepted.connect(self.__addNameToSandbox)
However, I want the Apply button to do the same but keep the child Dialog box open (as opposed to the OK button which closes it). How can I get that signal on the main window?
I have a method within the child dialog that I am able to run when Apply is clicked, but how to trigger an action in the main form with that, I have no idea.
buttonBox.button( QtGui.QDialogButtonBox.Apply ).clicked.connect( self.add )
I've tried using some of the other signals like finished, but I can't figure that one out either.
Create a signal in the dialog and connect it to the clicked of the apply button, and then use a signal to connect it in your main form:
class YourDialog(QtGui.QDialog):
applyClicked = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(YourDialog, self).__init__(parent):
# ...
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
apply_button = buttonBox.button(QtGui.QDialogButtonBox.Apply)
apply_button.clicked.connect(self.applyClicked)
# ...
self.__nameDialog.accepted.connect(self.__addNameToSandbox)
self.__nameDialog.applyClicked.connect(self.__applyfunc)
You need to declare QtCore.pyqtSignal applied as a class variable and then fire it up with self.applied.emit()
Then you'll be able to use it:
self.__nameDialog.applied.connect(self.__applyPressed)

Multiple messages in screen PyQt5

Here is my code
app = QApplication(sys.argv)
loginWindow = loadUi('~/mainwindow.ui')
okconnect = loadUi('~/okconnect.ui')
def prueba2(test):
print(test + " Testing2")
def prueba(test):
print (test)
okconnect.show()
okconnect.getvmsButton.clicked.connect(lambda: prueba2(test))
loginWindow.show()
loginWindow.connectButton.clicked.connect(lambda: prueba("test"))
sys.exit(app.exec_())
When I press "connect" button, a new window is opened, with a button, "getvmsButton", when I press this button, its show in console the print line in def prueba2(test), but if I close the window, and then I click again in connect button, the window open again and "getvmsButton" is pressed again, the console show 2 messages instead of 1. If I repeat the process, more messages are showed.
What should I change to show only one messages when I close and open several times the window?
When you close your GUI by 'x' doesn't mean you disconnected the button click signal, therefore, every time you click the 'connect' button, the loginWindow will create a new button.clicked event and keep the old ones. A quick solution to this is to define a close-event for the 'x' clicks. Here provided is just a way to close the old signal events.
from PyQt5.QtWidgets import QWidget
OKConnect(QWidget):
def __init__(self):
super().__init__()
self.okconnect = loadUi('~/okconnect.ui')
self.okconnect.closeEvent = self.closeEvent
def closeEvent(self, event):
print("testing2 closing")
# to close the old getvmsButton signals
self.okconnect.getvmsButton.disconnect()
# Here below is exactly your code
app = QApplication(sys.argv)
loginWindow = loadUi('~/mainwindow.ui')
okconnect = OKConnect()
def prueba2(test):
print(test + " Testing2")
def prueba(test):
print (test)
okconnect.show()
okconnect.getvmsButton.clicked.connect(lambda: prueba2(test))
loginWindow.show()
loginWindow.connectButton.clicked.connect(lambda: prueba("test"))
sys.exit(app.exec_())
I am not sure about your .ui files, the code may not work on yours.

Python tkinter raise exceptions and wait for button press

I'm new in Tkinter and I'm currently trying to create a small game. When something happens in the game I want to create a pop-up window which will inform the user about any changes. This is the code that I have written for it.
def message(self, text):
top = tkinter.Toplevel(width=50, height=25)
top.title("Message")
msg = tkinter.Message(top, text=text)
msg.pack()
ok = tkinter.Button(top, text="OK", command=top.destroy)
ok.pack()
My two questions are:
Can I replace this by an exception that will create an "Error Message" window? If it isn't necessary then can I use it to be raised by the exception?
I want the user to be forced to see and read the message, so how can I freeze the main window(the user can't click on anything else) until he presses the OK button on the pop-up window?
Use:
top.grab_set()
To show Error Message you can use tkmessagebox.showerror().

How to create a Button from code in WPF and Python?

I need to build multiple buttons, but I can't display any button! this is my code of a WPF application with IronPython 2.7..
I've tried this in two different ways, with "Grid.Children.Add(button)" and without that but anything displays..
XAML:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
x:Name="NewWindow" Height="564.22" Width="993.2">
<Grid x:Name="grid" Margin="0,0,75.2,92.4">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Content="Create a Button from code" HorizontalAlignment="Left"
Margin="712,418,0,0" VerticalAlignment="Top" Width="167" Height="61"
Click="CreateButtons_Click"/>
</Grid>
</Window>
CODE:
import clr
clr.AddReferenceToFileAndPath("IronPython.Wpf.dll")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")
clr.AddReferenceByPartialName("IronPython")
clr.AddReferenceByPartialName("Microsoft.Scripting")
import wpf
from System.Windows import Application, Window, Controls
from System.Windows.Forms import Form, Button
class NewWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'NewWindow.xaml')
def CreateButtons_Click(self, sender, e):
self.myButton = Button()
self.myButton.Name="boton1"
self.myButton.Text="prueba"
self.myButton.Size = Size(75,23)
self.myButton.Location = Point(0,0)
#Add to grid
self.grid.Children.Add(self.myButton)
That shows an error:
expected UIElement, got Button
If I skip that error and erase the line self.grid.Children.Add(self.myButton), it doesnt get an error, but doesnt show any button either.
How i can show my button in there by python code? (New at python and wpf)
I figured it out what was the problem!! (So easy i can't beieve it!)
The error of UIElement was because (I didnt know that there was two kind of buttons, im sorry!) I was importing Button from System.Windows.Forms and the correct button has to be imported from System.Windows.Controls
Nice day, everybody!

Categories

Resources