I am wondering what's the best way to add a clickable item to a QComboBox() in PySide?
here my combobox function so far.
def setTreeWidgetsComboBox(self, index, items, currVariation, node=None):
mainComboBoxWidget = QtGui.QWidget()
mainComboBoxLayout = QtGui.QVBoxLayout()
self.decayComboBox = QtGui.QComboBox()
mainComboBoxLayout.addWidget(self.decayComboBox)
mainComboBoxLayout.setContentsMargins(0,0,0,0)
mainComboBoxWidget.setLayout(mainComboBoxLayout)
if len(items) != 1:
for x in items:
try:
i = x.split('_')[1]
except:
i = x
continue
self.decayComboBox.addItem(i)
else:
self.decayComboBox.addItem(items[0])
i = self.decayComboBox.findText(currVariation, QtCore.Qt.MatchFixedString)
if i >= 0:
self.decayComboBox.setCurrentIndex(i)
self.decayComboBox.addItem('new variation..')
self.decayComboBox.setFixedHeight(20)
self.nmcTableWidget.setIndexWidget(index, mainComboBoxWidget)
return self.decayComboBox
i = self.decayComboBox.findText(currVariation, QtCore.Qt.MatchFixedString)
if i >= 0:
self.decayComboBox.setCurrentIndex(i)
self.decayComboBox.addItem('new variation..')
self.decayComboBox.setFixedHeight(20)
self.nmcTableWidget.setIndexWidget(index, mainComboBoxWidget)
return self.decayComboBox
now I want the 'new variation..' entry to have a click event.
Do I have to overwrite the whole QComboBox Class with a custom delegate or is there some way to add the entry as QComboBox widget and make it clicked.connect?
sorry if that's a basic question. I'm still not very advanced in PySide.
thank you.
of course currentIndexChanged did the trick.
Related
I'm creating an application where I need to make a checklist with a list given to me from another class. The user will check the checkboxes next to the items they want and then click a button. For those rows that were checked, I'd like to print "You checked number ___." in the neighboring QBoxGroup's QLabel.
(In my real application, I'm iterating through classes, where I will call a function within the class). I'm having a hard time iterating through my list since I have to check if the box is checked and whether or not the name is the name I'd like to print (the printed statement is different than the actual name because in my application I'm going to call a function within the class whose row I'm in).
I'm also not sure how to work this where I can print more than one statement if the user checks multiple boxes with QLabel. I might have to make it where the user can only select one row at a time, but this is a smaller issue than the one above.
from PyQt5.QtWidgets import (QApplication, QTabWidget, QVBoxLayout, QWidget, QGridLayout, QLabel, QGroupBox,
QListView, QPushButton)
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtCore import Qt
import sys, os
class MyPage(QWidget):
def __init__(self):
super().__init__()
self.app = QApplication(sys.argv)
self.screen = self.app.primaryScreen()
self.size = self.screen.size()
self.mydata = None
# These numbers are arbitrary and seemed
# to have the best balance
self.textWidth = self.size.width() * 0.64
self.chooseWidth = self.size.width() * 0.29
self.createTextGroup()
self.createStatsGroup()
self.layout = QGridLayout()
self.layout.addWidget(self.TextGroup, 0, 0, 0, 1)
self.layout.addWidget(self.StatsGroup, 0, 1)
self.setLayout(self.layout)
self.show()
# The left side of AnalysisTab containing the textbox
# where the analysis will be shown
def createTextGroup(self):
self.TextGroup = QGroupBox("Analysis")
self.TextGroup.setFixedWidth(self.textWidth)
self.setStyleSheet("font: 15pt Tw Cen MT")
# Here is where the analysis will go
self.analysis = QLabel()
self.layout = QGridLayout()
self.layout.addWidget(self.analysis)
self.TextGroup.setLayout(self.layout)
# The right side of AnalysisTab containing a checklist of tests that
# may be run on the data and a button to press to run the tests
def createStatsGroup(self):
self.StatsGroup = QGroupBox("Statistics Tests")
self.StatsGroup.setFixedWidth(self.chooseWidth)
self.setStyleSheet("font: 15pt Tw Cen MT")
# List widgets where users will choose what analysis
# they would like ran on their data
self.statsAnalysis = QListView()
self.model = QStandardItemModel(self.statsAnalysis)
for member in myList(self):
item = QStandardItem(member)
item.setCheckable(True)
check = Qt.Unchecked
item.setCheckState(check)
self.model.appendRow(item)
self.statsButton = QPushButton("Analyze")
self.statsButton.clicked.connect(self.statsButtonClicked)
self.statsAnalysis.setModel(self.model)
self.layout = QGridLayout()
self.layout.addWidget(self.statsAnalysis, 0, 0, 0, 1)
self.layout.addWidget(self.statsButton, 1, 1)
self.StatsGroup.setLayout(self.layout)
def statsButtonClicked(self):
model2 = self.model
for index in range(model2.rowCount()):
item = model2.item(index)
if item.checkState() == Qt.Unchecked and item == "One":
self.analysis.setText("You checked number 1")
elif item.checkState() == Qt.Unchecked and item == "One":
self.analysis.setText("You checked number 2")
elif item.checkState() == Qt.Unchecked and item == "One":
self.analysis.setText("You checked number 3")
elif item.checkState() == Qt.Unchecked and item == "One":
self.analysis.setText("You checked number 4")
elif item.checkState() == Qt.Unchecked and item == "One":
self.analysis.setText("You checked number 5")
else:
self.analysis.setText("You didn't check anything")
def myList(self):
thisList = ["One", "Two", "Three", "Four", "Five"]
return thisList
def runStatsWiz():
app = QApplication(sys.argv)
myPage = MyPage()
myPage.show()
app.exec_()
runStatsWiz()
Right now, the statsButtonClicked() function returns TypeError: 'QStandardItemModel' object is not callable
I've tried the information on these StackOverflow pages and I can't seem to figure out how to see the row's name and if the row is checked:
How do I get the Checked items in a Qlistview?
PyQt listView checkbox connect when checked/unchecked
How to iterate through a QStandardItemModel completely?
Iterating all items inside QListView using python
As I indicated in the comments you have a type since you have an attribute called self.model but you want to access using self.model().
On the other hand your logic is incorrect since for example it is not defined that it is row, on the other hand assuming that this error did not exist and you had 2 options checked with your logic you are writing "You checked number X" and then replace it with "You checked number Y".
The logic is to save the texts of the checked items in a list, and if that list is not empty then concatenate the information, otherwise indicate no items checked.
def statsButtonClicked(self):
checked_options = []
for index in range(self.model.rowCount()):
item = self.model.item(index)
if item is not None and item.checkState() == Qt.Checked:
checked_options.append(item.text())
if checked_options:
self.analysis.setText(
"\n".join(["You checked number {}".format(option) for option in checked_options])
)
else:
self.analysis.setText("You didn't check anything")
I have a QlistWidgets with some data in it and QlineEdit.
I want if QlistWidgets item is clicked it should show in QlineEdit.
Below is the screenshots
and this is my link to the my project
https://github.com/saurav389/Smart_Payroll_Management/blob/master/Department.py
I have tried in pyqt5 on windows
This is My code which add item from database
connection = sqlite3.connect('NewEmployee.db')
c = connection.cursor()
c.execute('SELECT Department FROM Department')
count = 0
for row in c.fetchall():
item = self.listWidget_DepartView.item(count)
raw = str(row).replace("('", "").replace("',)", "")
item.setText(_translate("Dialog", raw))
count = count + 1
self.listWidget_DepartView.setSortingEnabled(__sortingEnabled)
QListWidget has a signal called itemClicked() that carries the item that you can use to get the associated text:
# ...
self.listWidget_DepartView.itemClicked.connect(self.on_clicked)
# ...
def on_clicked(self, item):
self.lineEdit_AddDepart.setText(item.text())
Another possible solution is to use the clicked() signal from QAbstractItemView since QListWidget inherits from that class.
# ...
self.listWidget_DepartView.clicked.connect(self.on_clicked)
# ...
def on_clicked(self, index):
self.lineEdit_AddDepart.setText(index.data())
This question already has an answer here:
how to get a widget from QListWidgetItem
(1 answer)
Closed 4 years ago.
I can't find anything related in the internet and have been trying for hours now. Maybe also my whole attempt on the code is wrong. Not sure how this is done normally.
I am creating a custom widget with a few lables and an icon inside every row of a qlistwidget.
later on selection change I want to read the current rows , custom widgets data.
But I can't figure out how .
I got this custom widget:
class CustomCatalogWidget(QtGui.QWidget):
def __init__(self, catalogWidget, size):
super(CustomCatalogWidget, self).__init__()
self.mainLayout = QtGui.QHBoxLayout()
#reconstruct catalog items
self.thumbnail = catalogWidget.getThumbnailPixmap()
if not self.thumbnail:
return
self.thumbnail = self.thumbnail.scaled(size, size, QtCore.Qt.KeepAspectRatio)
self.name = catalogWidget.getNodeName()
self.thumbnailLocation = catalogWidget.getDiskThumbnailLocation()
# reconstruct finish
self.labelImage = QtGui.QLabel()
self.labelImage.setPixmap(self.thumbnail)
self.labelName = QtGui.QLabel(self.name)
self.timestamp = datetime.fromtimestamp(catalogWidget.getRenderEndTime())
self.labelRenderEndTime = QtGui.QLabel(self.timestamp.strftime('%Y-%m-%d %H:%M:%S'))
self.mainLayout.addWidget(self.labelImage)
self.mainLayout.addWidget(self.labelName)
self.mainLayout.addWidget(self.labelRenderEndTime)
self.setLayout(self.mainLayout)
which is attached to a qlistwidget inside my main class:
self.catalogBox = QtGui.QListWidget()
self.insertThumbnailsFromCatalog(self.catalogBox)
self.catalogBox.selectionModel().selectionChanged.connect(functools.partial (self.catalogBoxSelectionChanged, self.catalogBox))
this function is filling the catalogBox from inside the main
class:
def insertThumbnailsFromCatalog(self, boxLayout):
#CATALOG ROUTINE
#append all catalog items ot the window.
boxLayout.clear()
for catalogItem in CatalogManager.Catalog.GetCatalogItems(slot=1):
if catalogItem:
cw = CustomCatalogWidget(catalogItem, self.thumbnailSizeSlider.value())
itemWidget = QtGui.QListWidgetItem()
itemWidget.setSizeHint(QtCore.QSize(130,20))
boxLayout.addItem(itemWidget)
boxLayout.setItemWidget(itemWidget, cw)
#catalogBox.addWidget(QHLine())
and now I am trying to access the Custom catalog widget on selection changed.
I need to know what is written in the label self.labelName or self.labelRenderEndTime
And I don't seem to find the qlabels inside the qlistwidgetitems.
def catalogBoxSelectionChanged(self, boxLayout):
row = boxLayout.currentRow()
currentItem = boxLayout.currentItem()
for ch in currentItem.listWidget().children():
if ch.__class__.__name__ == 'QAbstractListModel':
print ch.children()
print dir(ch)
#for x in boxLayout.currentItem().listWidget().children():
# if x.__class__.__name__ == 'QWidget':
#print x.children()
oh actually I found out how to access it:
for ch in currentItem.listWidget().children():
for x in ch.children():
for i in x.children():
if i.__class__.__name__ == 'QLabel':
print i.text()
I have a QListView which displays a list of items using PyQt in Python. How can I get it to return a qlistview specific item when searched for?
For example, if I have the following Qlistview with 4 items, how can I get the item which contains text = dan? or bring it to the top of the list. Also, the search doesn't need to be completely specific, If I type "da" I'd like it to return dan or items that starts with "da" and possibly bring it to the top of the list
My Qlistview is defined as follows:
from PyQt4 import QtCore, QtGui
import os
import sys
class AppView(QtGui.QDialog):
def __init__(self, parent=None):
super(AppView, self).__init__(parent)
self.resize(400, 400)
self.ShowItemsList()
def ShowItemsList(self):
self.setWindowTitle("List")
buttonBox = QtGui.QDialogButtonBox(self)
buttonBox.setOrientation(QtCore.Qt.Horizontal)
buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
listview = QtGui.QListView(self)
verticalLayout = QtGui.QVBoxLayout(self)
verticalLayout.addWidget(listview)
verticalLayout.addWidget(buttonBox)
buttonBox.accepted.connect(self.close)
model = QtGui.QStandardItemModel(listview)
with open("names-list.txt") as input:
if input is not None:
item = input.readlines()
for line in item:
item = QtGui.QStandardItem(line)
item.setCheckable(True)
item.setCheckState(QtCore.Qt.PartiallyChecked)
model.appendRow(item)
listview.setModel(model)
listview.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
view = AppView()
view.show()
sys.exit(app.exec_())
I fixed it like this. I made my model an instance variable beginning with self so that I can access it from another function.
def searchItem(self):
search_string = self.searchEditText.text() # Created a QlineEdit to input search strings
items = self.model.findItems(search_string, QtCore.Qt.MatchStartsWith)
if len(items) > 0:
for item in items:
if search_string:
self.model.takeRow(item.row()) #take row of item
self.model.insertRow(0, item) # and bring it to the top
else:
print "not found"
I am writing an app that dynamically adds and removes widgets to a QScrollView. The code below, using Qt3 and python, will give me dynamic widgets, but when I add too many to be seen, no scroll bar appears. It is not yet scrollable. I've put the relevant pieces of code below.
Any answers must be in Qt3 because my company only uses Qt3. I'm new to programming and Qt in general.
PL = parser.Plist()
class EC_Conf_App(QDialog):
def __init__(self,parent = None,name = None,modal = 0,fl = 0):
QDialog.__init__(self,parent,name,modal,fl)
self.gridLayout = QGridLayout(self)
self.scrollArea = QScrollView(self)
self.scrollArea.setGeometry(0, 0, 369, 286)
self.Form1Layout = QGridLayout(self.scrollArea)
self.gridLayout.addWidget(self.scrollArea, 0, 0)
for item in PL.plist:
self.section_create(item.name, item.variables)
def section_create(self, name, variables):
# ADD ROW BUTTON
for key, value in sorted(variables.iteritems()):
if len(value) > 3: # if there is more than one option for the combobox
self.addButton = QPushButton(self.scrollArea, name + '_AddButton')
self.addButton.setText('Add Row')
self.Form1Layout.addWidget(self.addButton, self.Ay, self.Ax)
self.addButton.show()
self.connect(self.addButton,SIGNAL("clicked()"),self.add_rows)
def add_rows(self):
self.addButton = self.sender()
self.addButton.name()
copy_class = self.addButton.name()
clean_name = copy_class[:-10]
for item in PL.plist:
if item.name == clean_name:
PL.insert(item.name, item.heading, item.variables)
self.remove_widgets()
break
def remove_widgets(self):
for item in self.widgets:
item.deleteLater()
self.Form1Layout.remove(item)
self.construct()
def construct(self):
for item in PL.plist:
self.section_create(item.name, item.variables)
The only way to use a layout with a QScrollView is to set the layout on its viewport(), not the view itself. This is documented.
Replace self.Form1Layout = QGridLayout(self.scrollArea) with
self.Form1Layout = QGridLayout(self.scrollArea.viewport())
This question deals with the same problem for Qt4/5.