Triggering action when QTableView selection is changed [duplicate] - python

I have a problem with my PyQt button action. I would like to send a String with the Function but I got this Error:
TypeError: argument 1 has unexpected type 'NoneType'
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QAction
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtGui import *
from PyQt5.uic import *
app = QApplication(sys.argv)
cocktail = loadUi('create.ui')
def mixCocktail(str):
cocktail.show()
cocktail.showFullScreen()
cocktail.lbl_header.setText(str)
widget = loadUi('drinkmixer.ui')
widget.btn_ckt1.clicked.connect(mixCocktail("string"))
widget.show()
sys.exit(app.exec_())

As suggested by user3030010 and ekhumoro it expects a callable function. In which case you should replace that argument with lambda: mixCocktail("string")
AND ALSO don't use str it's a python built-in datatype I have replaced it with _str
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QAction
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtGui import *
from PyQt5.uic import *
app = QApplication(sys.argv)
cocktail = loadUi('create.ui')
def mixCocktail(_str):
cocktail.show()
cocktail.showFullScreen()
cocktail.lbl_header.setText(_str)
widget = loadUi('drinkmixer.ui')
widget.btn_ckt1.clicked.connect(lambda: mixCocktail("string"))
widget.show()
sys.exit(app.exec_())
More about lambda functions: What is a lambda (function)?

instead of this
widget.btn_ckt1.clicked.connect(mixCocktail("string"))
write
widget.btn_ckt1.clicked.connect(lambda:mixCocktail("string"))

Related

How to use QTest.keySequence?

I'm trying to test if a shortcut is working using PyQt5 and QTest. Here is my code:
Main.py
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QPushButton
class Window(QWidget):
def __init__(self):
super().__init__()
self.more_btn = QPushButton("More")
self.more_btn.clicked.connect(self.on_clicked)
self.more_btn.setShortcut(QKeySequence.Undo)
vbox = QVBoxLayout()
vbox.addWidget(self.more_btn)
self.setLayout(vbox)
def on_clicked(self):
print("Item clicked")
test_main.py
import sys
import unittest
from PyQt5.QtGui import QKeySequence
from PyQt5.QtTest import QTest
from PyQt5.QtWidgets import QApplication
from Main import Window
class MainTestCase(unittest.TestCase):
def test_main(self):
app = QApplication(sys.argv)
form = Window()
QTest.keySequence(form, QKeySequence.Undo)
When I run test_main, item_clicked should be printed, but it doesn't. I tried to debug the program and set the breatpoint at the print("Item clicked") line, it didn't stop. It seems that QTest.keySequence didn't work. Why? How should I make it work?

To turn back from 2nd window to 1st window (different files)

An application is being created with a large number of different windows.
The bottom line is that I am trying to get from the main window (by clicking button) to the client window. There is "Back" button in the clients window, which should return the user to the main window.
Both codes are in different files. The problem occurs at the stage of pressing the "Customers" button (Process finished with exit code -1073740791 (0xC0000409)).
Moreover, if everything is in one file, then everything works fine. But only here the program is not planned to be small, so I don't want to put a huge code in one file.
Welcome_Screen.py
import sys
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QDialog, QApplication
import Customers
class WelcomeScreen(QDialog):
def __init__(self):
super(WelcomeScreen, self).__init__()
loadUi('screens/welcomescreen.ui', self)
self.CustomerData.clicked.connect(self.go_to_CustomerData)
def go_to_CustomerData(self):
client = Customers.CustomerScreen()
widget.addWidget(client)
widget.setCurrentIndex(widget.currentIndex() + 1)
# main
app = QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('Icons/MainIcon.png'))
app.setApplicationDisplayName('Bonus Program')
welcome = WelcomeScreen()
widget = QtWidgets.QStackedWidget()
widget.addWidget(welcome)
widget.setFixedWidth(600)
widget.setFixedHeight(475)
widget.show()
try:
sys.exit(app.exec_())
except:
print("Exiting")
Customers.py
import sys
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QDialog, QApplication, QWidget, QMessageBox, QTableWidget, QTableWidgetItem, QTableView
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtGui import QIcon
import Welcome_Screen as ws
import sqlite3
db_path = 'Bonus_db.sqlite'
class CustomerScreen(QDialog):
def __init__(self):
super(CustomerScreen, self).__init__()
loadUi("screens/customerscreen.ui", self)
self.back_btn.setIcon(QIcon('Icons/Back.png'))
self.back_btn.setIconSize(QtCore.QSize(45, 60))
self.back_btn.clicked.connect(self.go_Back_to_WelcomeScreen)
# self.SoldTos.clicked.connect(self.gotoSoldTos)
def go_Back_to_WelcomeScreen(self):
welcome = ws.WelcomeScreen()
ws.widget.addWidget(welcome)
ws.widget.setCurrentIndex(ws.widget.currentIndex() + 1)
Customer_app = QApplication(sys.argv)
cust_window = CustomerScreen()
cust_window.show()
sys.exit(Customer_app.exec_())

Pyinstaller/CXFreeze bundle keeps rerunning the project on an infinite loop on mac

I ran pyinstaller --windowed --onedir Yuro.py and through troubleshooting I realized that my ipython console causes this infinite loop and I do not know how to stop it. When I click the finished pyinstaller bundle the project keeps rerunning on an infinite loop.
This is my app window starter code:
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setWindowIcon(QIcon('images/icons8-lion-96.png'))
app.setApplicationName("YuroPy IDE")
window = Window()
screen = app.primaryScreen()
size = screen.size()
window.resize(round(size.width() - size.width()/20), round(size.height() - size.height()/7))
qr = window.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
window.move(qr.topLeft())
window.show()
sys.exit(app.exec())
and this is my ipython qtconsole code:
USE_KERNEL = 'python3'
def make_jupyter_widget_with_kernel():
"""Start a kernel, connect to it, and create a RichJupyterWidget to use it
"""
kernel_manager = QtKernelManager(kernel_name=USE_KERNEL)
kernel_manager.start_kernel()
kernel_client = kernel_manager.client()
kernel_client.start_channels()
jupyter_widget = RichJupyterWidget()
jupyter_widget.kernel_manager = kernel_manager
jupyter_widget.kernel_client = kernel_client
return jupyter_widget
I also tried using CXFreeze, I didn't receive any error but the bundle kept running infinitely. Is this normal? and if its not how do I cope with it. I also added multiprocess.freeze_support() but it didn't help! These are all my imports:
from PyQt5.QtWidgets import QApplication, QTextEdit, QWidget, QPlainTextEdit, QTabBar, QPushButton, QMainWindow, QMenuBar, QAction, QVBoxLayout, QToolBar, QToolButton, QMenu, QLineEdit, QTreeView, QFileSystemModel, QTabWidget, QTreeWidget, QTreeWidgetItem, QStyle, QAbstractItemView, QHBoxLayout, QSplitter, QLabel, QDesktopWidget, QStylePainter, QStyleOptionButton, QInputDialog, QFileDialog, QMessageBox
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtGui import QKeySequence, QFont, QIcon, QFontMetrics, QTextCursor, QPainter, QColor, QImage
from PyQt5.QtCore import pyqtSlot, QRect, pyqtSignal, QDir, Qt, QUrl, QSocketNotifier, QSize
from PyQt5 import QtSvg
from PyQt5.Qsci import QsciScintilla, QsciLexerPython, QsciLexerCSS, QsciLexerHTML, QsciLexerJavaScript, QsciLexerCustom, QsciAPIs
import PyQt5
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.manager import QtKernelManager
from pathlib import Path
from pylint import lint
from pylint.reporters.text import TextReporter
import os
import re
#os.environ['QT_API'] = 'pyqt5'
import subprocess
import sys
import shutil
import pickle
import threading
import webbrowser
import locale, pty, struct, termios

Qt module alternative for PyQt6

I'm just migrating my application from PyQt5 to PyQt6. I understand that the Qt module has been removed in Qt6. I have stuff like 'Qt.AlignCenter', 'Qt.ToolButtonTextUnderIcon', 'Qt.LeftToolBarArea', which are no longer working. Is there any alternative for this functionality in Qt6?
The Qt module only exists in PyQt5 (not in Qt5) that allowed access to any class or element of any submodule, for example:
$ python
>>> from PyQt5 import Qt
>>> from PyQt5 import QtWidgets
>>> assert Qt.QWidget == QtWidgets.QWidget
That module is different from the Qt namespace that belongs to the QtCore module, so if you want to access Qt.AlignCenter then you must import Qt from QtCore:
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QLabel
def main():
app = QApplication(sys.argv)
w = QLabel()
w.resize(640, 498)
w.setAlignment(Qt.Alignment.AlignCenter)
w.setText("Qt is awesome!!!")
w.show()
app.exec()
if __name__ == "__main__":
main()
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QApplication, QMainWindow, QStyle, QToolBar
def main():
import sys
app = QApplication(sys.argv)
toolbar = QToolBar()
toolbar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
icon = app.style().standardIcon(QStyle.StandardPixmap.SP_DesktopIcon)
toolbar.addAction(icon, "desktop")
w = QMainWindow()
w.addToolBar(Qt.ToolBarAreas.LeftToolBarArea, toolbar)
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Currently, the AlignCenter and others can be found under AlignmentFlag enum:
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QPushButton, QVBoxLayout
def create_widget():
layout = QVBoxLayout()
button = QPushButton('Cancel')
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(button)

QListWidgetItem objects are unhashable, it is a bug or there's a reason?

I stumbled upon this (it is, obviously, an extract from a bigger application):
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
if __name__ == '__main__':
app = QApplication(sys.argv)
d = {}
widget = QWidget()
d[widget] = 'hashable'
item = QListWidgetItem('abc')
d[item] = 'unhashable'
If you run this, on the last line you get:
TypeError: unhashable type: 'PySide2.QtWidgets.QListWidgetItem'
As far as I can tell any Qt object can be used as dict keys, just like any user-defined class instances.
I'm running PySide2 5.13.0, Python 3.6.4 on Windows 7. I get the same error on Ubuntu 18.04, Python 3.6.9, PySide 5.9.0a1.
Thanks for any hint.
QListWidgetItem (similar to QTableWidgetItem and QTreeWidgetItem) is not hashtable since a QListWidgetItem associated with a row can change without notification unlike QObjects such as QWidget, QPushButton, etc.
If your goal is to associate information with a QListWidgetItem then you can use the setData() and data() methods.
import sys
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QListWidget, QListWidgetItem, QWidget
if __name__ == "__main__":
app = QApplication(sys.argv)
w = QListWidget()
for i in range(10):
it = QListWidgetItem("abc-{}".format(i))
it.setData(Qt.UserRole, "data-{}".format(i))
w.addItem(it)
def on_currentItemChanged():
current = w.currentItem()
print(current.data(Qt.UserRole))
w.currentItemChanged.connect(on_currentItemChanged)
w.show()
sys.exit(app.exec_())

Categories

Resources