Огромная сетка кнопок ужасно тормозит, кнопки не активируются

В моем проекте у меня есть 256 крошечных кнопок в одном макете сетки 16x16. (Да, это заняло целую вечность.) Редактирование и запуск моей программы сейчас очень тормозит. Кроме того, по какой-то странной причине Qt не позволяет мне включить ни одну из кнопок, но другие кнопки сбоку работают нормально?

Есть ли простой способ определить, какой квадрат сетки был нажат, не имея кучи кнопок? (Может быть, например, следовать за курсором по изображению?)

Кроме того, когда каждый «квадрат» сетки щелкнут, он становится «выделенным», и он должен быть единственным выбранным «квадратом». (Подумайте об этом как об огромной шахматной доске)

Вот картинка: http://gyazo.com/988cdbb59b3d1f1873c41bf91b1408fd

Позже мне нужно будет сделать это снова для сетки размера 54x54 (2916 кнопок), и я ДЕЙСТВИТЕЛЬНО не хочу делать это кнопка за кнопкой.

Спасибо за ваше время, я надеюсь, вы понимаете мой вопрос :)


person mrg95    schedule 20.08.2013    source источник
comment
Пожалуйста, покажите соответствующий код. Также: QGraphicsView может быть более подходящим в некоторых обстоятельствах.   -  person Mat    schedule 20.08.2013
comment
Соответствующего кода нет. Просто прочитайте мой вопрос. Это не проблема кодирования.   -  person mrg95    schedule 20.08.2013
comment
У вас есть вещи, которые ужасно тормозят, а вы предоставляете только изображение. Как мы должны помочь вам с этим? Я очень не хочу делать это кнопка за кнопкой, вызывая сомнения в структуре вашего существующего кода. Есть ли простой способ [...]? да, математика довольно проста, но это не правильное решение - решение состоит в том, чтобы исправить то, что вызывает отставание (или использовать другую технику, т.е. QGraphicsView может быть лучше, но не говорит, не зная подробности того, чем вы сейчас занимаетесь.)   -  person Mat    schedule 20.08.2013
comment
Шутки в сторону? Нужно ли мне загружать видео задержки для вас? Использование других функций в моей программе и ее редактирование в режиме QtDesigner запаздывает. Кнопка за кнопкой означает, что я размещал, изменял размер, упорядочивал, называл и перемещал каждую кнопку по одной. У меня столько кнопок, у меня программа лагает. Я ищу более простую альтернативу созданию огромной сетки кнопок.   -  person mrg95    schedule 20.08.2013
comment
Нет, я хочу увидеть код. Меня не интересуют картинки, видео или описание кода — ничто из этого не говорит мне, что именно вы делаете. Если вы создаете такую ​​сетку с помощью Qt Designer, это, вероятно, начало вашей проблемы - должно выглядеть довольно уродливо.   -  person Mat    schedule 20.08.2013
comment
Что не так с использованием Qt Designer? Это не выглядит уродливо, это выглядит именно так, как я хочу. Какой код вы хотите, чтобы я вам показал. Я не писал никакого кода, я просто разместил много кнопок, что не имеет значения. ИЩУ АЛЬТЕРНАТИВУ. В основном, что бы вы сделали тип вопроса....   -  person mrg95    schedule 20.08.2013
comment
Я говорю о коде, который должен выглядеть уродливо, если только Qt Designer не позволяет вам определить правильный массив или сетку кнопок, которые хранятся в правильном типе коллекции, а не в одной 100 различных независимых переменных в вашем пользовательском интерфейсе. класс. Я уже предлагал тебе альтернативу. Второй — закодировать этот виджет самостоятельно с разумной структурой кнопок.   -  person Mat    schedule 20.08.2013
comment
Я смущен. Не будет ли это все еще отставать? Потому что это все еще просто набор кнопок?   -  person mrg95    schedule 20.08.2013
comment
Послушайте, я понятия не имею - как я мог, я понятия не имею, какой код вы запускаете или как он подключен.   -  person Mat    schedule 20.08.2013
comment
Лучшим способом создания сетки было бы сделать это программно. Это может занять немного больше времени, чтобы макет выглядел абсолютно идеально, но это позволит вам быстро переключиться на сетку любого размера, просто изменив некоторые параметры функции.   -  person RobbieE    schedule 20.08.2013
comment
QGraphicsView кажется тем, что вам нужно. Хотя я не совсем уверен, что ты делаешь. Мне кажется, что у вас есть какое-то изображение, которое вы хотите разделить на сетку и определить, какая ячейка была нажата.   -  person thuga    schedule 20.08.2013
comment
Что ты пытаешься сделать? Я не уверен, что ваша текущая реализация (просто перетаскивание тысяч кнопок в сетке, чтобы определить, какая позиция нажата?) - это самый простой способ сделать то, что вы ищете. Почти каждый отдельный объект (на основе Qwidget) может иметь mousePressEvent, который может возвращать текущее положение мыши, что позволит вам получить местоположение щелчка мыши, не используя так много кнопок.   -  person g19fanatic    schedule 20.08.2013


Ответы (3)


Вы можете сделать это простым способом, я объяснил почти все в коде, но если у вас есть какие-либо вопросы по этому поводу, не стесняйтесь спрашивать, и, пожалуйста, примите этот ответ, если он решил вашу проблему :)

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import * 

class DrawImage(QMainWindow): 
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.setWindowTitle('Select Window')

        #you can set grid size here ... 8x8, 16x16 , for bigger numbers (54x54) be sure your image is big enough, because QWidget can't be smaller then ~20 pixels
        self.gridSize = 16

        mainWidget = QWidget()
        self.setCentralWidget(mainWidget)
        self.scene = QGraphicsScene()
        view = QGraphicsView(self.scene)
        layout = QVBoxLayout()
        layout.addWidget(view)
        mainWidget.setLayout(layout)
        self.image = QImage('image.JPG')# put your image name here, image (suppose to be grid) must be at the same folder or put full path
        pixmapItem = QGraphicsPixmapItem(QPixmap(self.image), None, self.scene)
        pixmapItem.mousePressEvent = self.pixelSelect


    def pixelSelect( self, event ):
        #add whatever you want to this widget,any functionality or you can add image for example, I've simply colored it
        wdg = QWidget()
        layout = QVBoxLayout()
        palette =  QPalette(wdg.palette())
        palette.setBrush(QPalette.Background, QColor(200,255,255))
        wdg.setPalette(palette)
        wdg.setLayout(layout)
        self.scene.addWidget(wdg)

        #calculate size and position for added widget
        imageSize = self.image.size()
        width = imageSize.width()
        height = imageSize.height() 

        #size
        wgWidth = float(width)/self.gridSize  
        wgHeight =  float(height)/self.gridSize
        wdg.setFixedSize(wgWidth,wgHeight)

        #position       
        wgXpos = int(event.pos().x()/wgWidth) * wgWidth
        wgYpos = int(event.pos().y()/wgHeight) * wgHeight
        wdg.move(wgXpos,  wgYpos)

        #which square is clicked?
        print "square at row ", int(event.pos().y()/wgHeight)+1,", column ",int(event.pos().x()/wgWidth)+1, "is clicked"

def main():
    app = QtGui.QApplication(sys.argv)
    form = DrawImage()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

Кроме того, если вы хотите отобразить простое квадратное изображение поверх изображения сетки, посмотрите вопрос/решение, которое у меня было: other-qgraphicspixmapitem/18564630?noredirect=1#18564630">QGraphicsPixmapItem не будет отображаться поверх другого QGraphicsPixmapItem

person Aleksandar    schedule 29.08.2013
comment
Я использую С++. Я написал это в заголовке, но чертовы модераторы всегда это убирают. Сводит меня с ума - person mrg95; 04.09.2013
comment
О, извините, я этого не видел. В любом случае, вы можете получить идею из данного кода Python (и из кода по данной ссылке) и перевести его на C++. Если вы хотите попробовать код Python: я использую Python2.6, PyQt4.7, eclipse с PyDev. Удачи. - person Aleksandar; 04.09.2013

Если вам действительно не нужен внешний вид кнопок, я бы создал подкласс QWidget, который реализует собственный paintEvent и отображает сетку необходимого размера (с учетом размера виджета). Затем в событиях мыши (вверх, вниз, перемещение и т. д.) вы можете вычислить, какой элемент сетки был нажат с помощью простой формулы. Вы можете визуализировать ячейки разными цветами, чтобы обозначить выделение или выделение.

P.S.: Мне бы очень хотелось опубликовать код из моих реализаций (я делал это два или три раза), но исходники находятся в моей старой компании :)

person erelender    schedule 02.09.2013

Вы просто создаете свой собственный QGridLayout, чтобы иметь возможность легко добавлять кнопки. Я отправил ответ на другой вопрос, показывающий, как последовательно заполнить созданный пользователем QGridLayout набором виджетов. Кнопки добавляются в соответствии с указанным вами максимальным количеством столбцов. (Примечание: это очень грубый пример, но для начала достаточно)

В вашем примере вы должны создать собственный макет сетки с 16 столбцами и просто добавить свои кнопки.

Чтобы узнать, какая кнопка была нажата (и упростить подключение), вы можете использовать QSignalMapper.

Для исследования задержки вы можете проверить количество (GDI-/User-) дескрипторов вашего приложения (например, с помощью ProcessExplorer). Количество дескрипторов не должно превышать 10 000.

Я не знаю, почему вы не можете включить кнопки.

person Exa    schedule 20.08.2013