Найти - Пользователи
Полная версия: PyQt button.clicked.connect
Начало » GUI » PyQt button.clicked.connect
1
heso
from PyQt4.QtGui import *
header1 = ['N', 'Тип', 'V', 'Pг', 'Pн', 'Qн']
header2 = ['Nн', 'Nк', 'R', 'X']
class MyTable(QTableWidget): 
    def __init__(self, header, *args):
        QTableWidget.__init__(self, *args) 
        self.header = header
        self.setHorizontalHeaderLabels(header)
        self.setColumnWidth(0, 40)
        self.setColumnWidth(1, 40)
        self.resizeRowsToContents()
class MainWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(250, 150, 400, 300)
        self.setWindowTitle("Ньютон")         
         
        tab_widget = QTabWidget() 
        tab1 = QWidget() 
        tab2 = QWidget() 
        tab3 = QWidget()
        tab_widget.addTab(tab1, "Узлы") 
        tab_widget.addTab(tab2, "Ветви")
        tab_widget.addTab(tab3, "Расчет")
        #Uzli on tab1
        table1 = MyTable(header1, 3, 6, tab1)
        table1.resize(500, 2222)
        table1.show()
        #Vetvi on tab2
        table2 = MyTable(header2, 1, 4, tab2)
        table2.resize(500, 2222)
        table2.show()
        #bottom del
        btn_del1 = QPushButton("delete row", tab1)
        btn_del1.clicked.connect(self.row)
        btn_del1.move(510, 0)
        #layout
        vbox = QVBoxLayout()
        vbox.addWidget(tab_widget)
        self.setLayout(vbox)
    def row(self):
        self.table1.removeRow(table1.selectedRows)
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    widget = MainWidget()
    widget.resize(640, 480)
    widget.show()
    sys.exit(app.exec_())
В теории, нажатие на кнопку должно удалить выделенную строку в таблице во вкладке “узлы”, однако выдает ошибку:
\Traceback (most recent call last):
  File "D:/tests/table.py", line 53, in row
    self.table1.removeRow(table1.selectedRows)
AttributeError: 'MainWidget' object has no attribute 'table1'
Как понимаю, вся проблема в классах, но что сделать, чтобы исправить ошибку - нужна помощь.


vrabey
heso
чтобы исправить ошибку
...
self.table1 = MyTable(header1, 3, 6, tab1)
...
    def row(self):
        self.table1.removeRow(self.table1.selectedRows)
доступ к атриуту происходит через аргумент self
это в частности
но в целом это исправление не решает задачу -
table1.selectedRows
здесь что то не правильно selectedRows - должен возвращать список а removeRow ждёт int
heso
Спасибо большое, в итоге решил пока остановиться на этом:
btn_del1 = QPushButton("delete row", tab1)
btn_del1.clicked.connect(self.delrow)
...
и функция:
def delrow(self):
        self.table1.removeRow(self.table1.currentRow())
Удаляет, правда, только по одной строке, но уже что-то.

Не уверен, что правильно задавать вопрос в этой теме(дабы в форуме не флудить), или лучше новую создать:
Данную кнопку необходимо использовать и для второй вкладки, но создавать для этого новую функцию, оперирующую со второй таблицей неразумно по идее.
Можно ли передать функции в качестве аргумента сам атрибут table1(а затем аналогично table2)? A не в ней самой прописывать вручную его: self.table1.removeRow(self.table1.currentRow()) и не создавать аналогичную функцию для 2 вкладки.
vrabey
heso
Данную кнопку необходимо использовать и для второй вкладки
сам не профи и поэтому не отвечаю а спрашиваю:
для каждого таба необходимо создать свою кнопку?
btn_del2 = QPushButton(“delete row”, tab2)…
но может сделать кнопку вне таба , что логичнее
а текущий таб определить не сложно:
self.connect(self.tab_widget, SIGNAL('currentChanged(int)'), self.switchingTabs)

def switchingTabs(self, i):
        self.currentIndex = i   
и в зависимости какой таб включен к такой таблице и обращается removeRow
так называем таблицы
tables = {}
tables[0] = MyTable(header1, 3, 6, tab1)
а это выполняем при нажатии кнопки:
tables[self.currentIndex].removeRow(tables[self.currentIndex].currentRow())
но я не проверял
heso
увы, но эта кнопка должна быть лишь на 2 табах, на третьем ее не будет.

Попробовал вот так:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
header1 = ['N', 'Тип', 'V', 'Pг', 'Pн', 'Qн']
header2 = ['Nн', 'Nк', 'R', 'X']
class MyTable(QTableWidget): 
    def __init__(self, header, *args):
        QTableWidget.__init__(self, *args) 
        self.header = header
        self.setHorizontalHeaderLabels(header)
        self.setColumnWidth(0, 40)
        self.setColumnWidth(1, 40)
        self.resizeRowsToContents()
class MainWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(250, 150, 400, 300)
        self.setWindowTitle("Ньютон")         
         
        self.tab_widget = QTabWidget()
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()
        self.tab_widget.addTab(self.tab1, "Узлы")
        self.tab_widget.addTab(self.tab2, "Ветви")
        self.tab_widget.addTab(self.tab3, "Расчет")
        #Uzli on tab1
        self.table = {}
        self.table[1] = MyTable(header1, 3, 6, self.tab1)
        self.table[1].resize(500, 2222)
        self.table[1].show()
        #Vetvi on tab2
        self.table[2] = MyTable(header2, 1, 4, self.tab2)
        self.table[2].resize(500, 2222)
        self.table[2].show()
        #bottom del1
        btn1_del1 = QPushButton("delete row", self.tab1)
        btn1_del1.clicked.connect(self.delrow)
        btn1_del1.move(510, 0)
        #bottom del2
        btn2_del1 = QPushButton("delete row", self.tab2)
        btn2_del1.clicked.connect(self.delrow)
        btn2_del1.move(510, 0)
        #layout
        vbox = QVBoxLayout()
        vbox.addWidget(self.tab_widget)
        self.setLayout(vbox)
        
    def delrow(self):
        self.connect(self.tab_widget, SIGNAL('currentChanged(int)'), self.switchingTabs)
        self.table[self.currentIndex].removeRow(self.table[self.currentIndex].currentRow())
    def switchingTabs(self, i):
        self.currentIndex = i
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    widget = MainWidget()
    widget.resize(640, 480)
    widget.show()
    sys.exit(app.exec_())

Однако
Traceback (most recent call last):
  File "D:/tests/table.py", line 68, in delrow
    self.table[self.currentIndex].removeRow(self.table[self.currentIndex].currentRow())
AttributeError: 'MainWidget' object has no attribute 'currentIndex'

Попытался прошагать в отладчике - даже не заходит в
 def switchingTabs(self, i):

На SO нашел, правда такой совет: http://stackoverflow.com/questions/18177750/pyqt-get-current-tab-number
И пример: http://codeprogress.com/python/libraries/pyqt/showPyQTExample.php?index=361&key=QTabWidgetCurrentChanged

Но все равно не могу понять.
heso
А ларчик то ведь просто открывался….

    def delrow(self):
self.table[self.tab_widget.currentIndex()].removeRow(self.table[self.tab_widget.currentIndex()].currentRow())

И всё)
vrabey
heso
увы, но эта кнопка должна быть лишь на 2 табах, на третьем ее не будет.
не знаю я бы всё равно бы сделал одну кнопку вне таба а при переключении табов
использовал бы в отношении кнопки метод или setVisible() или setDisabled()
для двух табов это может быть не актуально но если их будет десяток?
Зачем плодить лишние кнопки и лишний код
а по коду
removeRow(self.table[self.tab_widget.currentIndex()].currentRow())
у меня здесь всё время ноль а не индекс выделленой строки
heso
Индекс выделенной строки находится с помощью .currentRow().
.currentIndex() отображает индекс таба(начиная с нуля)

Насчет кнопки- действительно, стОит подумать над предложением, пока что получилось нечто такое:

from PyQt4.QtGui import *
header1 = ['N', 'Тип', 'V', 'Pг', 'Pн', 'Qн']
header2 = ['Nн', 'Nк', 'R', 'X']
class MyTable(QTableWidget): 
    def __init__(self, header, *args):
        QTableWidget.__init__(self, *args) 
        self.header = header
        self.setHorizontalHeaderLabels(header)
        self.setColumnWidth(0, 40)
        self.setColumnWidth(1, 40)
        self.resizeRowsToContents()
        self.verticalScrollBar()
class MainWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(250, 150, 400, 300)
        self.setWindowTitle("Ньютон")         
         
        self.tab_widget = QTabWidget()
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()
        self.tab_widget.addTab(self.tab1, "Узлы")
        self.tab_widget.addTab(self.tab2, "Ветви")
        self.tab_widget.addTab(self.tab3, "Расчет")
        #Uzli on tab1
        self.table = {}
        self.table[0] = MyTable(header1, 1, 6, self.tab1)
        self.table[0].resize(525, 430)
        self.table[0].show()
        #Vetvi on tab2
        self.table[1] = MyTable(header2, 1, 4, self.tab2)
        self.table[1].resize(525, 430)
        self.table[1].show()
        #bottom del1
        btn1_del = QPushButton("delete row", self.tab1)
        btn1_del.clicked.connect(self.delrow)
        btn1_del.move(530, 30)
        #bottom del2
        btn2_del = QPushButton("delete row", self.tab2)
        btn2_del.clicked.connect(self.delrow)
        btn2_del.move(530, 30)
        #bottom add1
        btn1_add = QPushButton("add row", self.tab1)
        btn1_add.clicked.connect(self.addrow)
        btn1_add.move(530, 0)
        #bottom add2
        btn2_add = QPushButton("add row", self.tab2)
        btn2_add.clicked.connect(self.addrow)
        btn2_add.move(530, 0)
        #layout
        vbox = QVBoxLayout()
        vbox.addWidget(self.tab_widget)
        self.setLayout(vbox)
        
    def delrow(self):
        self.table[self.tab_widget.currentIndex()].removeRow(self.table[self.tab_widget.currentIndex()].currentRow())
    def addrow(self):
        self.table[self.tab_widget.currentIndex()].insertRow(self.table[self.tab_widget.currentIndex()].rowCount())
        self.table[self.tab_widget.currentIndex()].resizeRowsToContents()
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    widget = MainWidget()
    widget.resize(640, 480)
    widget.show()
    sys.exit(app.exec_())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB