pyside2 how to query and create and delete dynamic widget - python

layout
layout (1)
QlineEdit
Qpushbutton
layout (2)
QlineEdit
Qpushbutton
Qpushbutton (3)
I try to create and delete layout(1,2) in layout.
it's work real time. layout(1,2) are dynamic number (1,2,3,~~)
Qpushbutton click -> parent layout and widget delete
and query text in QlineEdit
my test code --
#-*- coding:utf-8 -*-
import maya.cmds as mc
import os
import pprint
from PySide2 import QtWidgets, QtCore, QtGui
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentNameLine = QtWidgets.QLineEdit()
self.departmentNameLine.setFixedSize(100,20)
self.departmentPathLine = QtWidgets.QLineEdit()
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20,20)
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(self.mainLayout.count()-1, "sys.path.append :", self.sysAppendWidget)
def create_connections(self):
pass
def load_department(self):
self.departmentPlusBtn.setParent(None)
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for i in range(len(jsonDict["department"])):
layout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(layout)
departmentNameLine = QtWidgets.QLineEdit()
departmentNameLine.setText(jsonDict["department"][i][0])
departmentNameLine.setFixedSize(100,20)
departmentPathLine = QtWidgets.QLineEdit()
departmentPathLine.setText(jsonDict["department"][i][1])
departmentMinusBtn = QtWidgets.QPushButton("-")
departmentMinusBtn.setFixedSize(20,20)
cnt = self.departmentLayout.count()
departmentMinusBtn.clicked.connect(lambda x:self.remove_department(cnt))
layout.addWidget(departmentNameLine)
layout.addWidget(departmentPathLine)
layout.addWidget(departmentMinusBtn)
self.departmentLayout.insertWidget(self.departmentLayout.count(), self.departmentPlusBtn)
def remove_department(self, index):
print index
print self.departmentLayout.children()[0].layout().children()
if __name__ == "__main__":
try:
ui.close
except:
pass
ui = PreferenceUI()
ui.show()
I want
add path line
delete path line
query departmentNameLine, departmentPathLine text
i try ↑, but fail
i try in maya

To keep the logic tidy I have created a class that represents a row, then store the rows in a list to get the texts or to delete the row as I show below:
from functools import partial
from PySide2 import QtWidgets, QtCore, QtGui
class Widget(QtWidgets.QWidget):
def __init__(self, text1, text2, parent=None):
super().__init__(parent)
self.departmentNameLine = QtWidgets.QLineEdit(text1)
self.departmentNameLine.setFixedSize(100, 20)
self.departmentPathLine = QtWidgets.QLineEdit(text2)
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20, 20)
self.setContentsMargins(0, 0, 0, 0)
layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.departmentNameLine)
layout.addWidget(self.departmentPathLine)
layout.addWidget(self.departmentMinusBtn)
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.widgets = []
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(
self.mainLayout.count() - 1, "sys.path.append :", self.sysAppendWidget
)
def create_connections(self):
self.departmentPlusBtn.clicked.connect(self.add_row)
def load_department(self):
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for text1, text2 in jsonDict["department"]:
self.create_row(text1, text2)
def save_departament(self):
l = []
for widget in self.widgets:
l.append([self.departmentNameLine.text(), self.departmentPathLine.text()])
jsonDict = {"department": l}
print(jsonDict)
def add_row(self):
self.create_row("text1", "text2")
def create_row(self, text1="", text2=""):
widget = Widget(text1, text2)
widget.departmentMinusBtn.clicked.connect(partial(self.delete, widget))
self.departmentLayout.addWidget(widget)
self.widgets.append(widget)
def delete(self, widget):
if widget in self.widgets:
self.widgets.remove(widget)
widget.deleteLater()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = PreferenceUI()
w.show()
sys.exit(app.exec_())

Related

In PyQt5's QListWidget, how can I only show the tooltip for an item when the user chooses it?

I was inspired by this repo to add custom tooltip text to items when they are added to the QListWidget. However, I only want the tooltip message to appear when the item is chosen. How would I implement this?
Here is a GUI example that I have to test this feature:
import serial, time, sys
import serial.tools.list_ports
from PyQt5 import QtGui, QtWidgets, QtCore
import json, time
class GUI(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__init_ui()
def closeEvent(self, event):
super().closeEvent(event)
def __init_ui(self):
self.setWindowTitle('QListWidgetToolTipDemo')
self.history_log = HistoryList()
self.history_log.itemDoubleClicked.connect(self.history_item_selected)
self.history_log.returnPressed.connect(self.history_item_selected)
self.history_log.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.line_edit = QtWidgets.QLineEdit()
self.line_edit.returnPressed.connect(self.populate_history)
self.middle_layout = QtWidgets.QHBoxLayout()
self.middle_layout.addWidget(self.history_log)
self.middle_layout.addWidget(self.line_edit)
middle_layout_wrapper = QtWidgets.QWidget()
middle_layout_wrapper.setLayout(self.middle_layout)
middle_layout_wrapper.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# Sets full GUI layout
gui_layout = QtWidgets.QVBoxLayout()
gui_layout.addWidget(middle_layout_wrapper)
gui_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
gui_layout.setContentsMargins(QtCore.QMargins(0, 0, 0, 0))
self.setLayout(gui_layout)
def populate_history(self):
self.history_log.addItem(self.line_edit.text())
self.line_edit.clear()
def history_item_selected(self):
self.line_edit.setText(self.history_log.currentItem().text())
class HistoryList(QtWidgets.QListWidget):
returnPressed = QtCore.pyqtSignal()
def __init__(self) -> None:
super().__init__()
self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.setMouseTracking(True)
self.itemEntered.connect(self.__showToolTip)
def keyPressEvent(self, ev):
super().keyPressEvent(ev)
if ev.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.returnPressed.emit()
def addItem(self, aitem) -> None:
item = ''
text = ''
if isinstance(aitem, str):
item = QtWidgets.QListWidgetItem()
text = aitem
item.setText(text)
elif isinstance(aitem, QtWidgets.QListWidgetItem):
item = aitem
text = item.text()
self.setItemWidget(item, QtWidgets.QWidget())
super().addItem(item)
def __showToolTip(self, item: QtWidgets.QListWidgetItem):
text = item.text()
text_width = self.fontMetrics().boundingRect(text).width()
width = self.width()
info = {"time":str(time.time()), "entry":text}
info = json.dumps(info, indent=4)
item.setToolTip(info)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
console = GUI()
screensize = app.desktop().availableGeometry().size()
console.show()
exit(app.exec_())
Currently, the following is how a tooltip works for any item:
Example where only display tooltip when item is selected:
Expanding on the suggestion from musicamante in the comments, I was able to get tooltip to display only for the selected item by overriding the event method and watch for a tooltip event (inspired from this SO post)
import serial, time, sys
import serial.tools.list_ports
from PyQt5 import QtGui, QtWidgets, QtCore
import json, time
class GUI(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__init_ui()
def closeEvent(self, event):
super().closeEvent(event)
def __init_ui(self):
self.setWindowTitle('QListWidgetToolTipDemo')
self.history_log = HistoryList()
self.history_log.itemDoubleClicked.connect(self.history_item_selected)
self.history_log.returnPressed.connect(self.history_item_selected)
self.history_log.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.line_edit = QtWidgets.QLineEdit()
self.line_edit.returnPressed.connect(self.populate_history)
self.middle_layout = QtWidgets.QHBoxLayout()
self.middle_layout.addWidget(self.history_log)
self.middle_layout.addWidget(self.line_edit)
middle_layout_wrapper = QtWidgets.QWidget()
middle_layout_wrapper.setLayout(self.middle_layout)
middle_layout_wrapper.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# Sets full GUI layout
gui_layout = QtWidgets.QVBoxLayout()
gui_layout.addWidget(middle_layout_wrapper)
gui_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
gui_layout.setContentsMargins(QtCore.QMargins(0, 0, 0, 0))
self.setLayout(gui_layout)
def populate_history(self):
self.history_log.addItem(self.line_edit.text())
self.line_edit.clear()
def history_item_selected(self):
self.line_edit.setText(self.history_log.currentItem().text())
class HistoryList(QtWidgets.QListWidget):
returnPressed = QtCore.pyqtSignal()
def __init__(self) -> None:
super().__init__()
self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.setMouseTracking(True)
self.itemEntered.connect(self.__addToolTip)
self.items_tooltip_info_dict = dict()
def keyPressEvent(self, ev):
super().keyPressEvent(ev)
if ev.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.returnPressed.emit()
def event(self, e: QtCore.QEvent) -> bool:
if e.type() == QtCore.QEvent.ToolTip:
if not self.selectedItems():
QtWidgets.QToolTip.hideText()
return True
else:
index = self.indexFromItem(self.currentItem()).row()
info = json.dumps(self.items_tooltip_info_dict[index], indent=4)
QtWidgets.QToolTip.showText(e.globalPos(),info)
e.accept()
return super().event(e)
def addItem(self, aitem) -> None:
item = ''
text = ''
if isinstance(aitem, str):
item = QtWidgets.QListWidgetItem()
text = aitem
item.setText(text)
elif isinstance(aitem, QtWidgets.QListWidgetItem):
item = aitem
text = item.text()
self.setItemWidget(item, QtWidgets.QWidget())
super().addItem(item)
def __addToolTip(self, item: QtWidgets.QListWidgetItem):
text = item.text()
info = {"time":str(time.time()), "entry":text}
index = self.indexFromItem(item).row()
self.items_tooltip_info_dict[index] = info
if __name__ == "__main__":
app = QtWidgets.QApplication([])
console = GUI()
screensize = app.desktop().availableGeometry().size()
console.show()
exit(app.exec_())

QGroupBox buttons not showing

So basically I'm trying to make an updating QGroupBox with some QPushButtons inside of it, here's the "updating" method and it is always called right after the list is changed:
def repaintList(self):
btn_ls = []
for i in range(len(self.list)):
btn_ls.append(buttons.QPushButton("t"))
layout = QVBoxLayout()
for i in range(len(btn_ls)):
layout.addWidget(btn_ls[i])
it's pretty simple, I have a method that updates the list for me and I've tested the functionality with print(len(self.list)) and print(btn_ls) enough to know that the list updating works, and that the btn_ls is made properly, but I'm not sure why it's not updating on the actual screen.
I've made an example of a simplified version of what I'm trying to accomplish:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class TestWindow(QWidget):
def __init__(self):
super(TestWindow,self).__init__()
self.list = []
self.cont = TestContainer(self.list, "Test Box", self)
self.adder = AdderButton("Add one", self, self.list, self.cont)
layout = QVBoxLayout()
layout.addWidget(self.cont)
self.setLayout(layout)
self.setGeometry(200,200,200,200)
class TestContainer(QGroupBox):
def __init__(self,ls,ttl,pare):
super(TestContainer,self).__init__(ttl,pare)
self.list = ls
self.repaintButtons()
def repaintButtons(self):
btn_ls = []
for i in range(len(self.list)):
btn_ls.append(QPushButton(str(i),self))
print(self.list)
layout = QVBoxLayout()
for i in range(len(btn_ls)):
layout.addWidget(btn_ls[i])
self.setLayout(layout)
class AdderButton(QPushButton):
def __init__(self,txt,pare,ls,displ):
super(AdderButton,self).__init__(txt,pare)
self.disp = displ
self.list = ls
self.clicked.connect(self.addOne)
def addOne(self):
self.list.append(1)
self.disp.repaintButtons()
def main():
app = QApplication(sys.argv)
tw = TestWindow()
tw.show()
app.exec()
if __name__ == "__main__":
main()
The desired result is that every time I press the button a new QPushButton would appear on the screen...
After doing more research, I came across the update() function which basically repaints the QGroupBox. It works in the sense that it adds one button at a time and updates each time a button is added.
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class TestWindow(QWidget):
def __init__(self):
super(TestWindow,self).__init__()
self.list = []
self.cont = TestContainer(self.list, "Test Box", self)
self.adder = AdderButton("Add one", self, self.list, self.cont)
layout = QVBoxLayout()
layout.addWidget(self.cont)
self.setLayout(layout)
self.setGeometry(200,200,200,200)
class TestContainer(QGroupBox):
def __init__(self,ls,ttl,pare):
super(TestContainer,self).__init__(ttl,pare)
self.list = ls
self.layout = QVBoxLayout()
self.setLayout(self.layout)
def addButton(self):
self.layout.addWidget(QPushButton("thing"))
class AdderButton(QPushButton):
def __init__(self,txt,pare,ls,displ):
super(AdderButton,self).__init__(txt,pare)
self.disp = displ
self.list = ls
self.clicked.connect(self.addOne)
def addOne(self):
self.list.append(1)
self.disp.addButton()
self.disp.update()
def main():
app = QApplication(sys.argv)
tw = TestWindow()
tw.show()
app.exec()
if __name__ == "__main__":
main()
I has to use self.layout() instead of layout to see widgets.
def repaintButtons(self):
btn_ls = []
for i in range(len(self.list)):
btn_ls.append(QPushButton(str(i),self))
print(self.list)
layout = QVBoxLayout()
self.setLayout(layout) # it has to be before `self.layout()`
for i in range(len(btn_ls)):
self.layout().addWidget(btn_ls[i])
BTW: self.setLayout() has to be before self.layout()
But there is other problem.
Using again
layout = QVBoxLayout()
self.setLayout(layout)
doesn't remove previous layout and it doesn't remove previous buttons and finally it adds again the same buttons to layout.
You would need add only new buttons to layout instead of adding all buttons again.
Or you would have to remove widgets from layout before adding them again.
EDIT:
Code which adds new button without removing previous buttons
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class TestWindow(QWidget):
def __init__(self):
super(TestWindow,self).__init__()
self.list = []
self.container = TestContainer("Test Box", self, self.list)
self.adder = AdderButton("Add one", self, self.container)
layout = QVBoxLayout()
layout.addWidget(self.container)
self.setLayout(layout)
self.setGeometry(200,200,200,200)
class TestContainer(QGroupBox):
def __init__(self, title, parent, lst):
super(TestContainer,self).__init__(title, parent)
self.list = lst
layout = QVBoxLayout()
self.setLayout(layout)
# create buttons at start using `self.list`
for item in self.list:
self.layout().addWidget(QPushButton(str(item), self))
def addButton(self, item):
# add new item to `self.list` and create new button
self.list.append(item)
self.layout().addWidget(QPushButton(str(item), self))
class AdderButton(QPushButton):
def __init__(self, text, parent, target):
super(AdderButton,self).__init__(text, parent)
self.target = target
self.clicked.connect(self.addOne)
def addOne(self):
self.target.addButton(1)
def main():
app = QApplication(sys.argv)
tw = TestWindow()
tw.show()
app.exec()
if __name__ == "__main__":
main()
There are examples how to remove items but they don't work for me
Clear all widgets in a layout in pyqt
PyQt How to remove a layout from a layout

Widgets cross over the tab on Pyqt5

I am trying to build a simple desktop application which can show and play all the movies in one place. This app includes several tabs, which contain different categories of movies.
The problem is the widgets i put inside the tab windows cross over the tab title. I don't know why.
This is my code:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Filmler(QTabWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Filmler")
self.setWindowIcon(QIcon("film.jpg"))
self.setGeometry(200,100,1000,500)
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab3 = QWidget()
self.tab4 = QWidget()
self.tab1UI()
self.tab2UI()
self.tab3UI()
self.tab4UI()
self.addTab(self.tab1, "Hollywood")
self.addTab(self.tab2, "Bollywood")
self.addTab(self.tab3, "Uyghur")
self.addTab(self.tab4, "Zumra'nin Filmleri")
self.show()
def tab1UI(self):
# adding variables
# 1st movie
movie1_poster = QLabel()
movie1_poster.setPixmap(QPixmap("equalizer2.jpg"))
movie1_name = QLabel("Equalizer 2")
movie1_name.setAlignment(Qt.AlignCenter)
movie1_name.setFont(QFont("Times", 13))
movie1_link = QPushButton("izle")
vbox1 = QVBoxLayout()
vbox1.addWidget(movie1_name)
vbox1.addWidget(movie1_poster)
vbox1.addWidget(movie1_link)
vbox1.addStretch()
hbox = QHBoxLayout()
hbox.addLayout(vbox1)
hbox.addStretch()
self.setLayout(hbox)
def tab2UI(self):
pass
def tab3UI(self):
pass
def tab4UI(self):
pass
app = QApplication(sys.argv)
filmler = Filmler()
sys.exit(app.exec_())
This is the result.
Set parent self.tab1 to QHBoxLayout
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Filmler(QTabWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Filmler")
self.setWindowIcon(QIcon("film.jpg"))
self.setGeometry(200,100,1000,500)
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab3 = QWidget()
self.tab4 = QWidget()
self.tab1UI()
self.tab2UI()
self.tab3UI()
self.tab4UI()
self.addTab(self.tab1, "Hollywood")
self.addTab(self.tab2, "Bollywood")
self.addTab(self.tab3, "Uyghur")
self.addTab(self.tab4, "Zumra'nin Filmleri")
self.show()
def tab1UI(self):
# adding variables
# 1st movie
movie1_poster = QLabel()
movie1_poster.setPixmap(QPixmap("lena.jpg"))
movie1_name = QLabel("Equalizer 2")
movie1_name.setAlignment(Qt.AlignCenter)
movie1_name.setFont(QFont("Times", 13))
movie1_link = QPushButton("izle")
vbox1 = QVBoxLayout()
vbox1.addWidget(movie1_name)
vbox1.addWidget(movie1_poster)
vbox1.addWidget(movie1_link)
vbox1.addStretch()
hbox = QHBoxLayout(self.tab1) # + self.tab1
hbox.addLayout(vbox1)
hbox.addStretch()
# self.setLayout(hbox) # ---
def tab2UI(self):
pass
def tab3UI(self):
pass
def tab4UI(self):
pass
app = QApplication(sys.argv)
filmler = Filmler()
sys.exit(app.exec_())

pyqt closing a custom dialog in main window via mouse click

Q. is it possible, dialog closes itself and return color name just when user clicked or double clicked color item
Below is working example (hopefully to demonstrate problem). clicking on canvas area will pop up color dialog. currently user has to select color and then hit 'OK' button, where as intent is complete when user click on color. Just wanted to save user time, one bit.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic, QtMultimedia, QtMultimediaWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
colorsDict = { 'White': '0xFFFFFF','DarkGray': '0xA9A9A9','DarkSlateGray': '0x2F4F4F','LightSlateGray': '0x778899','DimGray': '0x696969','Gray': '0x808080','SlateGray': '0x708090','Black': '0x000000','DarkRed': '0x8B0000','Darkorange': '0xFF8C00','FireBrick': '0xB22222','Crimson': '0xDC143C','Salmon': '0xFA8072'}
def hexToQColor (h):
h = h.lstrip('#') # general usage safety
# h = h.lstrip('0x') # my use case
if h.find('0x') == 0:
h = h.split('0x')[1]
rgb = tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))
return QColor(rgb[0],rgb[1],rgb[2])
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# self.ui = uic.loadUi('ui/ffmpeg_colors.ui', self)
self.setWindowTitle("FFMPEG Color Picker")
self.listWidget = QListWidget()
self.readPrefs()
self.listWidget.setFlow(QListView.LeftToRight)
self.listWidget.setResizeMode(QListView.Adjust)
self.listWidget.setGridSize(QSize(32, 32))
self.listWidget.setSpacing(5)
self.listWidget.setViewMode(QListView.IconMode)
self.listWidget.itemClicked.connect(self.itemClicked)
self.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked)
layout = QVBoxLayout(self)
layout.addWidget(self.listWidget)
# OK and Cancel buttons
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def readPrefs(self):
"""
reading preferences from module for Data in UI
"""
for each in colorsDict.keys():
item = colorsDict[each]
listItem = QListWidgetItem()
listItem.setToolTip(each)
listItem.setSizeHint(QSize(30, 30))
color = hexToQColor(item)
listItem.setBackground(QBrush(color))
self.listWidget.addItem(listItem)
def itemClicked(self,item):
self.listWidget.setCurrentItem(item)
# self.accept()
def itemDoubleClicked(self,item):
c = item.background().color()
self.listWidget.setCurrentItem(item)
result = self.exec_()
return(c,result==QDialog.Accepted)
def getResults(self):
if self.exec_() == QDialog.Accepted:
item = self.listWidget.currentItem()
# print (item.toolTip())
return ( item.toolTip())
else:
return None
def getUserColor(self):
return (self.listWidget.currentItem().toolTip())
#staticmethod
def getFinalColor(parent=None):
dialog = FfmpegColorDialog(parent)
result = dialog.exec_()
color = dialog.getUserColor()
return(color,result==QDialog.Accepted)
class MainWindow(QMainWindow):
central_widget = None
layout_container = None
def __init__(self):
super(MainWindow, self).__init__()
self.central_widget = QWidget()
self.layout_container = QVBoxLayout()
self.central_widget.setLayout(self.layout_container)
self.setCentralWidget(self.central_widget)
self.layout_container.addWidget(GraphicsView())
class GraphicsView(QGraphicsView):
def __init__(self):
super(GraphicsView, self).__init__()
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.text = None
self.createText()
def createText(self):
self.text = QGraphicsTextItem()
font = QFont()
font.setPixelSize(40)
self.text.setFont(font)
self.text.setPlainText("Sample Text To Test")
self.scene.addItem(self.text)
def mousePressEvent(self, event):
r,ok = FfmpegColorDialog.getFinalColor()
hc = colorsDict[r]
rgb = hexToQColor(hc)
self.text.setDefaultTextColor(rgb)
if __name__ == '__main__':
app = QApplication(sys.argv)
# dia = FfmpegColorDialog()
# dia.show()
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Just connect the clicked signal of the QListWidget to the accept slot of FfmpegColorDialog:
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# ...
self.listWidget = QListWidget()
self.listWidget.clicked.connect(self.accept) # <---
# ...

Unable to resize QTableWidget

I m trying to resize a table widget inside a QVBoxlayout which I further add as a row to a QFormlayout in pyqt
I m currently adding a QVboxlayout which contains a table widget inside it as a row in a Qformlayout.
And the main aim is to strecth the Table widget till the end of the application window that it acquires the left over space on the window
Using the below code -
class PGSearchDetails():
def __init__(self,parent=None):
self.widget_pgsd = QWidget()
self.layout_pgsd = QFormLayout()
self.layout_pgsd.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy(2|1))
self.PG_Id = QLineEdit()
#rx = QRegExp("^\\D+[!,#,#,$,%,\^,&,*,(,),:,\",{,},?,<,>,|,+,-,~,]")
#rx = QRegExp(" (?!(#,#,$|%|\^|&|*|(|)|:|\"|{|}|?|<|>|\||+|-|~|!))[\\w]+")
str_rx = QRegExp("^[A-Za-z*]{20}(?!##$%^&*():\"\{\}?<>\|+-~!_-)")
adhr_rx = QRegExp("[A-Z0-9]{12}(?!##$%^&*():\"\{\}?<>\|+-~!_)")
val = QRegExpValidator(str_rx)
val3 = QRegExpValidator(adhr_rx)
self.PG_Id.setValidator(val3)
self.LastName = QLineEdit()
self.LastName.setValidator(val)
self.MobNum = QLineEdit()
qint_val = QIntValidator()
qint_val.setTop(10)
self.MobNum.setValidator(qint_val)
self.layout_pgsd.addRow("First Name",self.PG_Id)
self.layout_pgsd.addRow("Last Name",self.LastName)
self.layout_pgsd.addRow("Mobile Number",self.MobNum)
update_layout_pgsd = QHBoxLayout()
layout_test,table = dbv.Search_View(self.getT)
#layout_test.setGeometry(QRect(200,200,50,50))
#table.setMaximumHeight(800)
#table.setGeometry(200,200,200,200)
#table.setGeometry(1,1,1000,600)
table.resize(1000,600)
update_btn_pgsd = QPushButton('Update')
reset_btn_pgsd = QPushButton('Reset')
update_layout_pgsd.addWidget(update_btn_pgsd)
update_layout_pgsd.addWidget(reset_btn_pgsd)
self.layout_pgsd.addRow(update_layout_pgsd)
##Adding the Table Widget to FormLayot
self.layout_pgsd.addRow(layout_test)
update_btn_pgsd.clicked.connect(partial(self.database,table,self.MobNum,
self.LastName))
#self.widget.setLayout(self.layout_pgsd)
def returnLayout(self):
return self.layout_pgsd
def returnWidget(self):
return self.widget_pgsd
def getT(self,linedit):
print("LE--->",linedit.text())
QtableWidget setup ---
def Search_View(self):
print("Inside Search_view")
central_widget = QWidget() # Create a central widget
db_layout = QVBoxLayout()
#col_count = len(self.pg_details.__dict__.keys())
col_count = 3
table = QTableWidget() # Create a table
#central_widget.setGeometry(200,200,150,150)
#table.maximumSize()
#db_layout.setMaximumSize(200)
db_layout.setGeometry(QRect(0,0,100,30))
db_layout.addWidget(table)
##Tried resizing the Table widget but nothing seems to works
table.resize(1000,600)
table.setGeometry(0,2,1000,600)
#central_widget.resize(central_widget.sizeHint())
#central_widget.setColumnWidth(1000,600)
#db_layout.addItem(update_layout)
central_widget.setLayout(db_layout)
print("Geometry H--->",table.geometry().height())
print("Geometry W--->",table.geometry().width())
print("Geometry X--->",table.geometry().x())
print("Geometry Y--->",table.geometry().y())
return central_widget,table
After the resize function, The table geometry changes to 1000,600 but on the screen it is not reflected. On the app screen it remains the same size everytime
Also find the entire code which contains the Tablayouts as well and Stacked widget for individual radio buttons
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.tab_widget = MainTabWindow()
self.setCentralWidget(self.tab_widget)
self.show()
class MainTabWindow(QTabWidget):
def __init__(self,parent=None):
super(MainTabWindow, self).__init__(parent)
self.init_ui()
def init_ui(self):
self.setWindowTitle('PyQt5 Tab Example')
self.tab1 = QWidget()
self.addTab(self.tab1,"Search")
self.PGSearchTab()
def PGSearchTab(self):
print("Search Tab First Tab")
self.central_layout = QVBoxLayout()
self.stack1 = QWidget()
self.stack2 = QWidget()
self.stack3 = QWidget()
self.stack_widget = QStackedWidget()
button_layout = QHBoxLayout()
radio_button_1 = QRadioButton("Search")
radio_button_2 = QRadioButton("Add")
radio_button_3 = QRadioButton("Update")
button_layout.addWidget(radio_button_1)
button_layout.addWidget(radio_button_2)
button_layout.addWidget(radio_button_3)
self.central_layout.addItem(button_layout)
self.stack_widget.addWidget(self.stack1)
self.stack_widget.addWidget(self.stack2)
self.stack_widget.addWidget(self.stack3)
self.central_layout.addWidget(self.stack_widget)
radio_button_1.toggled.connect(lambda :self.SelectButtonCheck(radio_button_1))
self.setTabText(0,"Search")
update_layout = QHBoxLayout()
update_layout.setAlignment(QtCore.Qt.AlignBottom)
update_btn = QPushButton('Update')
reset_btn = QPushButton('Reset')
update_layout.addWidget(update_btn)
update_layout.addWidget(reset_btn)
self.tab1.setLayout(self.central_layout)
def SelectButtonCheck(self,b):
if b.text() == "Search":
if b.isChecked():
print(b.text()+ "is selected")
self.obj_pgsd = pgsd.PGSearchDetails()
layout = self.obj_pgsd.returnLayout()
if self.stack1.layout() is None:
self.stack1.setLayout(layout)
self.stack_widget.setCurrentIndex(0)
def main():
application = QApplication(sys.argv)
main_window = MainTabWindow()
main_window.show()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
I do not seem to understand what is I m missing here
Any pointers would be appreciated.
Also find the working code to execute the above layout setup.
#!/usr/local/bin/python3
import sys
from PyQt5.QtWidgets import (QApplication, QWidget,QMainWindow,QLineEdit,QAction,
QLabel,QPushButton,QVBoxLayout,
QTabWidget,QFormLayout,QHBoxLayout,
QRadioButton,QCheckBox,QTextEdit,
QListView,QDialogButtonBox,QSizePolicy,QCalendarWidget)
from PyQt5 import QtCore
import PyQt5.Qt
from PyQt5.Qt import *
from PyQt5.QtCore import pyqtSlot
from PyQt5 import QtSql
from functools import partial
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.tab_widget = MainTabWindow()
self.setCentralWidget(self.tab_widget)
self.show()
class MainTabWindow(QTabWidget):
def __init__(self,parent=None):
super(MainTabWindow, self).__init__(parent)
self.init_ui()
def init_ui(self):
self.setWindowTitle('PyQt5 Tab Example')
self.tab1 = QWidget()
self.addTab(self.tab1,"Search")
self.PGSearchTab()
def PGSearchTab(self):
print("Search Tab First Tab")
self.central_layout = QVBoxLayout()
self.stack1 = QWidget()
self.stack2 = QWidget()
self.stack3 = QWidget()
self.stack_widget = QStackedWidget()
button_layout = QHBoxLayout()
radio_button_1 = QRadioButton("Search")
radio_button_2 = QRadioButton("Add")
radio_button_3 = QRadioButton("Update")
button_layout.addWidget(radio_button_1)
button_layout.addWidget(radio_button_2)
button_layout.addWidget(radio_button_3)
self.central_layout.addItem(button_layout)
self.stack_widget.addWidget(self.stack1)
self.stack_widget.addWidget(self.stack2)
self.stack_widget.addWidget(self.stack3)
self.central_layout.addWidget(self.stack_widget)
radio_button_1.toggled.connect(lambda :self.SelectButtonCheck(radio_button_1))
self.setTabText(0,"Search")
update_layout = QHBoxLayout()
update_layout.setAlignment(QtCore.Qt.AlignBottom)
update_btn = QPushButton('Update')
reset_btn = QPushButton('Reset')
update_layout.addWidget(update_btn)
update_layout.addWidget(reset_btn)
self.tab1.setLayout(self.central_layout)
def SelectButtonCheck(self,b):
if b.text() == "Search":
if b.isChecked():
print(b.text()+ "is selected")
self.obj_pgsd = PGSearchDetails()
layout = self.obj_pgsd.returnLayout()
if self.stack1.layout() is None:
self.stack1.setLayout(layout)
self.stack_widget.setCurrentIndex(0)
class PGSearchDetails():
def __init__(self,parent=None):
self.widget_pgsd = QWidget()
self.layout_pgsd = QFormLayout()
self.layout_pgsd.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy(2|1))
self.PG_Id = QLineEdit()
#rx = QRegExp("^\\D+[!,#,#,$,%,\^,&,*,(,),:,\",{,},?,<,>,|,+,-,~,]")
#rx = QRegExp(" (?!(#,#,$|%|\^|&|*|(|)|:|\"|{|}|?|<|>|\||+|-|~|!))[\\w]+")
str_rx = QRegExp("^[A-Za-z*]{20}(?!##$%^&*():\"\{\}?<>\|+-~!_-)")
adhr_rx = QRegExp("[A-Z0-9]{12}(?!##$%^&*():\"\{\}?<>\|+-~!_)")
val = QRegExpValidator(str_rx)
val3 = QRegExpValidator(adhr_rx)
self.PG_Id.setValidator(val3)
self.LastName = QLineEdit()
self.LastName.setValidator(val)
self.MobNum = QLineEdit()
qint_val = QIntValidator()
qint_val.setTop(10)
self.MobNum.setValidator(qint_val)
self.layout_pgsd.addRow("First Name",self.PG_Id)
self.layout_pgsd.addRow("Last Name",self.LastName)
self.layout_pgsd.addRow("Mobile Number",self.MobNum)
update_layout_pgsd = QHBoxLayout()
layout_test,table = self.Search_View(self.getT)
#layout_test.setGeometry(QRect(200,200,50,50))
#table.setMaximumHeight(800)
#table.setGeometry(200,200,200,200)
#table.setGeometry(1,1,1000,600)
table.resize(1000,600)
update_btn_pgsd = QPushButton('Update')
reset_btn_pgsd = QPushButton('Reset')
update_layout_pgsd.addWidget(update_btn_pgsd)
update_layout_pgsd.addWidget(reset_btn_pgsd)
self.layout_pgsd.addRow(update_layout_pgsd)
##Adding the Table Widget to FormLayot
self.layout_pgsd.addRow(layout_test)
update_btn_pgsd.clicked.connect(partial(self.database,table,self.MobNum,
self.LastName))
#self.widget.setLayout(self.layout_pgsd)
def returnLayout(self):
return self.layout_pgsd
def returnWidget(self):
return self.widget_pgsd
def getT(self,linedit):
print("LE--->",linedit.text())
def Search_View(self,text):
print("Inside Search_view")
central_widget = QWidget() # Create a central widget
db_layout = QVBoxLayout()
#col_count = len(self.pg_details.__dict__.keys())
col_count = 3
table = QTableWidget() # Create a table
#central_widget.setGeometry(200,200,150,150)
#table.maximumSize()
#db_layout.setMaximumSize(200)
db_layout.setGeometry(QRect(0,0,100,30))
db_layout.addWidget(table)
##Tried resizing the Table widget but nothing seems to works
table.resize(1000,600)
table.setGeometry(0,2,1000,600)
#central_widget.resize(central_widget.sizeHint())
#central_widget.setColumnWidth(1000,600)
#db_layout.addItem(update_layout)
central_widget.setLayout(db_layout)
print("Geometry H--->",table.geometry().height())
print("Geometry W--->",table.geometry().width())
print("Geometry X--->",table.geometry().x())
print("Geometry Y--->",table.geometry().y())
return central_widget,table
def SqlExec(self,text):
db = QtSql.QSqlDatabase.addDatabase('QMYSQL')
db.setHostName('localhost')
db.setDatabaseName('Test')
db.setUserName('root')
db.open()
query = QtSql.QSqlQuery()
select = "select * from Test.PG_Details where PG_Id=?"# where PG_Id = 1"
query.prepare(select)
indexes = range(3)
print("TEXT----->",text)
query.addBindValue(text)
#query.exec_(select)
query.exec_()
print("Sizze----",query.size())
row_count = query.size()
db.record('PG_Details')
col_list = []
for i in range(db.record('PG_Details').count()):
print("FIELD----->",db.record('PG_Details').field(i).name())
col_list.append(db.record('PG_Details').field(i).name())
db.close()
return query,row_count,col_list
def database(self,table,text,text2):
text = text.text()
query_result,row_count,col_list = self.SqlExec(text)
i = 0
table.setColumnCount(3) #Set three columns
table.setRowCount(row_count)
table.setHorizontalHeaderLabels(col_list)
while query_result.next():
#print(query_result.value(i))
result_row = [query_result.value(index) for index in range(query_result.record().count())]
#print("RR--->",result_row)
for idx,val in enumerate(result_row):
#print("IDX----->",idx)
table.setItem(i, idx, QTableWidgetItem(val))
i = i + 1
def main():
application = QApplication(sys.argv)
main_window = MainTabWindow()
main_window.show()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
The problem is that QFormLayout makes every time you add a widget using addRow () uses strech, the solution is to use a QVBoxLayout, and in that QVBoxLayout is to pass the QFormLayout and the layout_test.
class PGSearchDetails():
def __init__(self,parent=None):
self.widget_pgsd = QWidget()
self.layout = QVBoxLayout() # <---
self.layout_pgsd = QFormLayout()
self.layout.addLayout(self.layout_pgsd) # <---
self.layout_pgsd.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy(2|1))
...
self.layout_pgsd.addRow(update_layout_pgsd)
##Adding the Table Widget to FormLayot
# self.layout_pgsd.addRow(layout_test)
self.layout.addWidget(layout_test) # <---
update_btn_pgsd.clicked.connect(partial(self.database,table,self.MobNum,
self.LastName))
def returnLayout(self):
return self.layout # <---

Categories

Resources