PyQt5 - CSV Import, Display и Scroll советы - Представления против виджетов, QTreeView против других - PullRequest
0 голосов
/ 08 апреля 2019

Меня попросили (для некоммерческой организации) написать приложение, которое будет работать на Pi и отобразить на экране список гонщиков, разделенных на 3 вертикальных секции (On Course (1), In Gate (1) и в очереди (до 50)).Не ожидается, что в разделе «В очереди» будут отображаться все записи - скажем, только следующие 10 слов.

Список изначально будет получен из файла CSV на USB-накопителе.Список на экране должен прокручиваться на основе внешнего входа, когда гонщики проходят стартовые ворота, с механизмом переопределения (экранные кнопки, аппаратные кнопки и т. Д.) Вверх или вниз в случае возникновения проблем.Каждая строка списка будет состоять из 3 или около того записей - например, номер нагрудника, имя и предыдущее время выполнения.

Прокрутка должна быть такой, как если бы три секции списка были одной секцией.то есть одно действие прокрутки должно измениться: гонщик On Course прокручивает верхнюю часть экрана, гонщик In Gate становится гонщиком On Course, а верхний гонщик In Queue становится следующим гонщиком In Gate.

Iменя попросили дать более подробное объяснение того, как будет работать прокрутка, пытаться что-то здесь смутить, но это помогает:

Стартовый экран:

Racer on Course:
  [blank]
Racer in Gate:
  10, Jo Blogs, 13.3
Racers in Queue:
  11, John Harrow, 13.4
  12, Lynne Graham, 13.5
  13, Lindsey Vonn, 14.5

Экран после первого 'scroll 'action:

Racer on Course:
  10  Jo Blogs  13.3
Racer in Gate:
  11, John Harrow, 13.4
Racers in Queue:
  12, Lynne Graham, 13.5
  13, Lindsey Vonn, 14.5

Экран после второго действия' scroll ':

Racer on Course:
  11,John Harrow,13.4
Racer in Gate:
  12,Lynne Graham,13.5
Racers in Queue:
  13,Lindsey Vonn,14.5

Нет необходимости редактировать или сохранять какие-либо данные - просто отображать в соответствии с CSV.

Я решил использовать Python 3 и PyQt5, поскольку они кроссплатформенные и широко используются, множество примеров, учебных пособий и т. Д.

За последние 15 лет я несколько раз использовал Pythonлет, но мои объектно-ориентированные навыки слабы, и я раньше не использовал Qt.

Пример CSV может выглядеть так:

10,Jo Blogs,13.3
11,John Harrow,13.4
12,Lynne Graham,13.5
13,Lindsey Vonn,14.5

Приложение (без загруженных данных) может выглядеть такэто:

До сих пор я прошел несколько учебных пособий, включая Zetcode: http://zetcode.com/gui/pyqt5 и собрал сам (или соединенные примеры) некоторый исходный код, который заставляет меня начать,но я застрял над несколькими фундаментальными вопросами, о которых я не знаю, чтобы принимать правильные решения сейчас, чтобы они не вызывали у меня значительных проблем позже.

  1. QTreeWidget / QTreeView правильный виджет Qt для использования для отображения?

  2. QTreeWidget против QtreeView - я понимаю разницу между данными, хранящимися в виджете, по сравнению с моделью данных и виджетомпросто отображение этих данных - но я не знаю, как мне и этому приложению выбрать правильный путь.

  3. Прокрутка строк через 3 виджета как единый объект - что самое простое / лучшее/ правильный способ установить это?

У меня есть несколько указаний относительно того, куда я мог бы пойти дальше:

Настройка TreeViews - https://pythonspot.com/pyqt5-treeview/

Загрузка CSV дата в виджет - pyqt - заполнение QTableWidget данными CSV

Любая положительная помощь, указатели, архитектурное направление приветствуется.

Большое спасибо

Мойпока код для справки ...

#!/usr/bin/python3
# -*- coding: utf-8 -*-

from PyQt5.QtWidgets import (QMainWindow, QTextEdit, QWidget, QLabel, QGridLayout, QLineEdit, QPlainTextEdit,
                             QTreeView, QAction, QFileDialog, QApplication, qApp)

from PyQt5.QtGui import QIcon
import sys


class Start(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        # Build Status Bar
        self.statusBar()

        # File Menu File > Open Action
        openFile = QAction(QIcon('open.png'), 'Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.showOpenDialog)

        # File Menu File > Exit Action
        exitAct = QAction(QIcon('exit.png'), '&Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(qApp.quit)

        # Build Menu Bar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)
        fileMenu.addAction(exitAct)

        self.widget = QWidget()
        self.setCentralWidget(self.widget)

        # Build Central Widget
        lblOnCourse = QLabel('Racer On Course:', self)
        lblInGate = QLabel('Racer In gate:', self)
        lblInQueue = QLabel('Racers In Queue:', self)

        grid = QGridLayout()
        grid.setSpacing(10)

        OnCourse = QTreeView()
        InGate = QTreeView()
        InQueue = QTreeView()

        InQueue.setRootIsDecorated(False)
        #InQueue.dataView.setAlternatingRowColors(True)

        grid.addWidget(lblOnCourse, 1, 0)
        grid.addWidget(OnCourse, 1, 1)

        grid.addWidget(lblInGate, 2, 0)
        grid.addWidget(InGate, 2, 1)

        grid.addWidget(lblInQueue, 3, 0)
        grid.addWidget(InQueue, 3, 1, 5, 1)

        self.widget.setLayout(grid)

        # Show QMainWindow
        self.showMaximized()
        #self.showFullScreen()
        #self.show()


    def showOpenDialog(self):
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/')

        if fname[0]:
            f = open(fname[0], 'r')

            with f:
                data = f.readlines()
                #self.textEdit.setText(data)

            self.statusBar().showMessage('Loaded: ' + str(len(data)) + '. ')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Start()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 14 апреля 2019

Итак, с помощью fiverr у меня теперь есть рабочий код. Заполнение данных в QTree решается так:

# Create some data:
data = ['XXX' for _ in range(8)]

# Create instance of QTreeView
IG = QTreeView()

# Create a View Model
IGM = self.prepModel(IG)

# Populate View Model
fillModel(IGM, data[1:2])


def prepModel(self, widget):
    # initialize a model
    model = QStandardItemModel()

    # remove indentation and headers
    widget.setIndentation(0)
    widget.setHeaderHidden(1)

    # add (data) model to widget
    widget.setModel(model)
    return model


def fillModel(self, model, data):
    for i, d in enumerate(data):
        model.setItem(i, QStandardItem(d))
    return

Различное (количество) строк в разных QTreeView производится путем заполнения QTreeViewModel различными (количествами) данных:

    def display(self):
        # show the first
        self.fillModel(self.OCM, self.data[0:1])

        # show the second
        self.fillModel(self.IGM, self.data[1:2])

        # show the first (n) of the rest
        #self.fillModel(self.IQM, self.data[2:self.displayMaxIQRows + 2])
        # show the full queue (-1 doesn't show last?)
        self.fillModel(self.IQM, self.data[2:len(self.data)])

Прокрутка выполняется путем перемещения данных между двумя массивами, перед тем как снова запустить «display» для повторного заполнения QTreeViewModel.

    def scroll(self):
        # add first element to past data
        self.pastData = self.pastData + self.data[0:1]

        # remove the first element from data
        self.data.pop(0)

        # refresh the racers list
        self.displayRacers()
        return

Надеюсь, это поможет кому-то еще в будущем.

Приветствие Кев

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...