The tablewidget gets overwritten by the next header - python

The header of the next group overwrites the table of the one before. Any ideas on how to protect the table before? I tried to use the spacer but it did not work. Any other ideas how I can solve the problem?
I have a header with e.g. an account number and a name. Below I want to list all the postings. But this program is not only for one account. It is for 100+ accounts to document the balances at a give date. (e.g. at the end of the year)
from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog, QWidget,
QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,QScrollArea,
QVBoxLayout,QListWidget,QTableWidget,QTableWidgetItem)
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, QSize, QDate
import sys
class Dialog(QDialog):
def __init__(self,parent=None):
super().__init__(parent)
self.setGeometry(64,64, 1000, 400)
self.setWindowTitle("test")
self.scrollarea = QScrollArea(self)
self.scrollarea.setFixedWidth(990)
self.scrollarea.setWidgetResizable(True)
widget = QWidget()
self.scrollarea.setWidget(widget)
self.layout_SArea = QGridLayout(widget)
self.layout_All = QVBoxLayout(self)
self.layout_All.addWidget(self.scrollarea)
for i in range(1,20,2):
self.layout_SArea.addWidget(QLabel("I am the header"),i,0)
self.tableWidget = QTableWidget()
self.tableWidget.setRowCount(10)
self.tableWidget.setColumnCount(12)
for x in range(10):
newitem = QTableWidgetItem()
newitem.setData( Qt.EditRole,'{:0,.0f}'.format(x))
newitem.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled )
newitem.setTextAlignment(Qt.AlignRight)
self.tableWidget.setItem(x, 0, newitem)
self.layout_SArea.addWidget(self.tableWidget,i+1,0,i+1,5)
self.layout_All.addLayout(self.layout_SArea)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Dialog()
sys.exit(dialog.exec_())

The row span argument indicates how many "row cells" the in the grid are occupied by the item, so it should not use the row index.
Change to:
self.layout_SArea.addWidget(self.tableWidget, i+1, 0, 1, 5)

Related

PyQt5 - Tabs having same objects

So I do not want to use a layout for any of the tabs. I will be using .setGeometry to place the objects, as there is many objects to be placed :)
The problem is: Any object created in Tab1.py and Tab2.py are appearing on all the tabs.
Tab3.py code is identical to Tab2.py (just a button)
I believe the issue is with the Parent/Child code, but not sure were I went wrong. Any guidance would be much appreciated. You can also ignore some of the imports, I just haven't gotten to that code yet :)
MainWindow.py
import os, sys, subprocess, atexit, PyQt5, pyodbc, time, datetime, getpass, csv, xlsxwriter
import Tab1, Tab2, Tab3
from PyQt5.QtWidgets import QApplication, QTabBar, QLayout, QLabel, QLineEdit, QMainWindow, QTabWidget, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QGroupBox, QRadioButton, QTextEdit, QCheckBox, QInputDialog, QFileDialog, QProgressBar, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import *
class MainWindow(QMainWindow):
# define main window size and position on screen
def __init__(MainWindow, parent=None):
super().__init__()
MainWindow.left = 50
MainWindow.top = 50
MainWindow.width = 720
MainWindow.height = 600
MainWindow.setGeometry(MainWindow.left,
MainWindow.top,
MainWindow.width,
MainWindow.height)
MainWindow.table_widget = MainWindowWidget(MainWindow)
MainWindow.setCentralWidget(MainWindow.table_widget)
MainWindowWidget()
class MainWindowWidget(QWidget):
def __init__(self, parent=None):
super(QWidget, self).__init__(parent)
# configure layout
self.layout = QVBoxLayout(self)
self.setLayout(self.layout)
# initialize tab screen
self.tabs = QTabWidget()
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab3 = QWidget()
self.layout.addWidget(self.tabs)
# add tabs
self.tabs.addTab(self.tab1, "Tab1")
self.tabs.addTab(self.tab2, "Tab2")
self.tabs.addTab(self.tab2, "Tab3")
# create first tab
Tab1.Tab1.CreateTab1(self)
Tab2.Tab2.CreateTab2(self)
Tab3.Tab3.CreateTab3(self)
def exit_handler(self):
print('closing application')
atexit.register(exit_handler(self))
# create main window and show it
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = MainWindow()
MainWindow.show()
sys.exit(app.exec_())
Tab1.py
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QMainWindow, QTabWidget, QWidget, QPushButton, QHBoxLayout, \
QVBoxLayout, QGroupBox, QRadioButton, QTextEdit, QCheckBox, QInputDialog, QFileDialog, QProgressBar, QTableWidget, \
QTableWidgetItem, QComboBox
import MainWindow
class Tab1(QMainWindow):
def CreateTab1(tab1, parent=None):
# reference number input box
tab1.label_input_reference_number = QLabel(tab1)
tab1.label_input_reference_number.setText('Reference Number')
tab1.label_input_reference_number.setGeometry(25, 80, 115, 20)
tab1.input_reference_number = QLineEdit(tab1)
tab1.input_reference_number.setGeometry(170, 80, 215, 20)
# add CheckGroupButton
tab1.Button = QPushButton(tab1)
tab1.Button.setText("Button")
tab1.Button.setGeometry(385, 105, 100, 20)
Tab2.py
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QMainWindow, QTabWidget, QWidget, QPushButton, QHBoxLayout, QGroupBox, QRadioButton, QTextEdit, QCheckBox, QInputDialog, QFileDialog, QProgressBar, QTableWidget, QTableWidgetItem
class Tab2(QMainWindow):
def CreateTab2(tab2):
# add button
tab2.Button = QPushButton(tab2)
tab2.Button.setText("Another button")
tab2.Button.setGeometry(300, 585, 100, 20)
Your problem is here:
self.tabs.addTab(self.tab1, "Tab1")
self.tabs.addTab(self.tab2, "Tab2")
self.tabs.addTab(self.tab2, "Tab3")
# create first tab
Tab1.Tab1.CreateTab1(self)
Tab2.Tab2.CreateTab2(self)
Tab3.Tab3.CreateTab3(self)
You have all of the tab controls being owned by the parent. (Also, you have tab2 in there twice.) You want:
self.tabs.addTab(self.tab1, "Tab1")
self.tabs.addTab(self.tab2, "Tab2")
self.tabs.addTab(self.tab3, "Tab3")
Tab1.Tab1.CreateTab1(tab1)
Tab2.Tab2.CreateTab2(tab2)
Tab3.Tab3.CreateTab3(tab3)
However, this is an odd way to do it. You should have Tab1, Tab2 and Tab3 derive from QWidget, and do this:
self.tab1 = Tab1.Tab1()
self.tab2 = Tab2.Tab2()
self.tab3 = Tab3.Tab3()
That way, you don't need a strange class method to configure things.
Here's why: the tab{i} variable you're passing into each CreateTab{i}(tab{i}) function is the same variable each time; self as referenced in MainWindow. Here's what I'd do; instead of passing self into the call Tab{i}.Tab{i}.CreateTab{i}(self), instead pass in self.tab{i}, the variable you stored earlier. That way separate objects (not the same self i.e. MainWindow) are receiving the separate children widgets.

Change color in QLineEdit in Python

I changed the background color to gray and the label color to yellow, but the color of the boxes was also changed to gray and the text inside of them changed color to yellow.
I want to change the colors of the QLineEdit to white and the text inside of them to black, but I don't know how to do it
import sys, re
from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QFormLayout, QCheckBox, QComboBox, QSpinBox, QDialogButtonBox, QMessageBox, QErrorMessage, QToolTip, QPushButton, QLineEdit, QLabel, QTextEdit, QMainWindow, QGroupBox, QHBoxLayout, QVBoxLayout
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt
import ctypes
class Dialog(QDialog):
NumGridRows = 10
NumButtons = 4
def __init__(self):
super(Dialog, self).__init__()
self.createFormGroupBox()
self.setStyleSheet("background:rgb(66,85,99);")
buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttonBox1 = QPushButton('Export',self)
buttonBox1.setStyleSheet("background:rgb(255,199,44);")
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
buttonBox.setStyleSheet("background:rgb(255,199,44);")
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.formGroupBox)
mainLayout.addWidget(buttonBox)
mainLayout.addWidget(buttonBox1)
self.setLayout(mainLayout)
self.setWindowTitle("Cuadro seguimiento")
def createFormGroupBox(self):
self.formGroupBox = QGroupBox("New")
self.formGroupBox.setStyleSheet("color: rgb(255,199,44);")
layout = QFormLayout()
layout.addRow(QLabel("Fecha"), QLineEdit())
layout.addRow(QLabel("Dias abiertos"), QLineEdit())
layout.addRow(QLabel("Nombre del caso"), QLineEdit())
layout.addRow(QLabel("Responsable"), QLineEdit())
layout.addRow(QLabel("Ok MKT"), QLineEdit())
layout.addRow(QLabel("Solicitud Lotus"), QCheckBox())
layout.addRow(QLabel("OS"), QLineEdit())
layout.addRow(QLabel("Monto"), QLineEdit())
layout.addRow(QLabel("Fecha cierre"), QLineEdit())
layout.addRow(QLabel("Comentario"), QLineEdit())
self.formGroupBox.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Dialog()
sys.exit(dialog.exec_())

Disable higlighting selected items in QListWidget pyqt5

How do I disable higlighting selected items in QListWidget pyqt5?
Tried the following which didn't work:
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem, QGridLayout, QLabel, QWidget
app = QApplication([])
widget = QWidget()
listWidget = QListWidget()
item = QListWidgetItem('Pogba', listWidget)
layout.addWidget(listWidget)
#Attempt
palette = QPalette()
palette.setColor(QPalette.Highlight, listWidget.palette().color(QPalette.Base))
palette.setColor(QPalette.HighlightedText, listWidget.palette().color(QPalette.Text))
listWidget.setPalette(palette)
widget.setLayout(layout)
widget.show()
app.exec()
And the following only makes the item grey instead of blue:
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem, QGridLayout, QLabel, QWidget
app = QApplication([])
widget = QWidget()
listWidget = QListWidget()
item = QListWidgetItem('Pogba', listWidget)
layout.addWidget(listWidget)
#Other attempt
listWidget.setFocusPolicy(Qt.NoFocus)
widget.setLayout(layout)
widget.show()
app.exec()
Is there another way to achieve this?

Why my QToolButton which I try to make collapsible doesn't collapse properly?

guys.
Asking for your help to troubleshoot my test script.
I am practicing to make collapsible button with widgets inside.
Script was mainly taken from another question in stackoverflow about collapsible buttons.
So I am trying to put under QTabWidget my class CollpsibleBox(QWidget). Problem is that my CollapsibleBox is acting very weird - buttons are jumping , sometimes it doesn't open/close properly.
I was wondering if it's some mistake in placing correctly my widget under QTabWidget or is there some problem with animation?
import random
from PySide2.QtGui import QPixmap, QBrush, QColor, QIcon, QPainterPath, QPolygonF, QPen, QTransform
from PySide2.QtCore import QSize, Qt, Signal, QPointF, QRect, QPoint, QParallelAnimationGroup, QPropertyAnimation, QAbstractAnimation
from PySide2.QtWidgets import QMainWindow, QDialog, QVBoxLayout, QHBoxLayout, QGraphicsView, QGraphicsScene, QFrame, \
QSizePolicy, QGraphicsPixmapItem, QApplication, QRubberBand, QMenu, QMenuBar, QTabWidget, QWidget, QPushButton, \
QSlider, QGraphicsPolygonItem, QToolButton, QScrollArea, QLabel
extraDict = {'buttonSetA': ['test'], 'buttonSetB': ['test']}
tabList = ['Main', 'Extra']
_ui = dict()
class MainWindow(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent=parent)
self.create()
def create(self, **kwargs):
_ui['mainLayout'] = QVBoxLayout()
_ui['tabWidget'] = QTabWidget()
_ui['mainLayout'].addWidget(_ui['tabWidget'])
for tab in tabList:
_ui['tab' + tab] = QWidget()
_ui['tabWidget'].addTab(_ui['tab' + tab], tab)
_ui['tabExtra'].layout = QVBoxLayout()
_ui['tabExtra'].setLayout(_ui['tabExtra'].layout)
_ui['content'] = QWidget()
_ui['tabExtra'].layout.addWidget(_ui['content'])
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
box = CollapsibleBox(name)
vlay.addWidget(box)
lay = QVBoxLayout()
for j in range(8):
label = QLabel("{}".format(j))
color = QColor(*[random.randint(0, 255) for _ in range(3)])
label.setStyleSheet(
"background-color: {}; color : white;".format(color.name())
)
label.setAlignment(Qt.AlignCenter)
lay.addWidget(label)
box.setContentLayout(lay)
self.setLayout(_ui['mainLayout'])
class CollapsibleBox(QWidget):
def __init__(self, name):
super(CollapsibleBox, self).__init__()
self.toggle_button = QToolButton(text=name, checkable=True, checked=False)
self.toggle_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.toggle_button.setArrowType(Qt.RightArrow)
self.toggle_button.pressed.connect(self.on_pressed)
self.toggle_animation = QParallelAnimationGroup(self)
self.content_area = QScrollArea(maximumHeight=0, minimumHeight=0)
self.content_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.content_area.setFrameShape(QFrame.NoFrame)
lay = QVBoxLayout(self)
lay.setSpacing(0)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self.toggle_button)
lay.addWidget(self.content_area)
self.toggle_animation.addAnimation(QPropertyAnimation(self, b"minimumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self, b"maximumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self.content_area, b"maximumHeight"))
def on_pressed(self):
checked = self.toggle_button.isChecked()
self.toggle_button.setArrowType(Qt.DownArrow if not checked else Qt.RightArrow)
self.toggle_animation.setDirection(QAbstractAnimation.Forward
if not checked
else QAbstractAnimation.Backward
)
self.toggle_animation.start()
def setContentLayout(self, layout):
lay = self.content_area.layout()
del lay
self.content_area.setLayout(layout)
collapsed_height = (self.sizeHint().height() - self.content_area.maximumHeight())
content_height = layout.sizeHint().height()
for i in range(self.toggle_animation.animationCount()):
animation = self.toggle_animation.animationAt(i)
animation.setDuration(500)
animation.setStartValue(collapsed_height)
animation.setEndValue(collapsed_height + content_height)
content_animation = self.toggle_animation.animationAt(self.toggle_animation.animationCount() - 1)
content_animation.setDuration(500)
content_animation.setStartValue(0)
content_animation.setEndValue(content_height)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.setGeometry(500, 100, 500, 500)
window.show()
sys.exit(app.exec_())
The problem is that you are only adding two widgets to the full layout, and the layout will try to place them as better as possible (tipically at the center of the area that is available for each widget, based on its size hints).
You could either set the alignment of the widget for the layout (placing the buttons on top of their available space):
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
box = CollapsibleBox(name)
vlay.addWidget(box, alignment=Qt.AlignTop)
Or add a stretch to the bottom of the layout:
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
# ...
vlay.addStretch(1)
which will position all buttons on top of the layout.
As a side note, I'd suggest you to avoid the dictionary logic for the ui, as it might become very confusing and prone to errors. If you really need to do that for some (I hope, very good) reason that's ok, but please avoid it when asking questions: it makes really hard to read your code, and people might end up just ignoring your question at all.

QScrollArea does not attach to label

I am trying to display an image label with scrollbars within a Box layout.
However, the scroll area appears at the wrong place with the wrong size.
Could you please tell me what I am doing wrong?
import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QScrollArea
from PyQt5.QtGui import QPixmap
class ApplicationWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
main_widget = QWidget(self)
btn = QPushButton("Bye", self)
btn.clicked.connect(self.close)
img = QPixmap("1.jpg")
label = QLabel(main_widget)
label.setPixmap(img)
scrollArea = QScrollArea(main_widget)
scrollArea.setWidgetResizable(True)
scrollArea.setWidget(label)
l = QVBoxLayout(main_widget)
l.addWidget(label)
l.addWidget(btn)
self.setCentralWidget(main_widget)
def closeEvent(self, ce):
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
aw = ApplicationWindow()
aw.show()
app.exec_()
The result is:
The problem is that instead of adding the QLabel to QVBoxLayout you must add the QScrollArea. You must change:
l.addWidget(label)
to
l.addWidget(scrollArea)

Categories

Resources