В моем проекте у меня есть 256 крошечных кнопок в одной сетке 16×16. (Да, это заняло вечность.) Редактирование и запуск моей программы сейчас очень запаздывает. Кроме того, по какой-то странной причине Qt не разрешает мне включать любую из кнопок, но другие кнопки сбоку работают нормально?
Есть ли простой способ определить, по какому квадрату сетки щелкнули, не имея связки кнопок? (Может быть, как следование за курсором над изображением?)
Кроме того, когда щелкается каждый «квадрат» сетки, он становится «выделением», и он должен быть единственным выбранным «квадратом». (Думайте об этом как огромная шахматная доска)
Вот картинка: http://gyazo.com/988cdbb59b3d1f1873c41bf91b1408fd
Позже мне нужно будет сделать это снова для сетки размером 54×54 (2916 кнопок), и я ДЕЙСТВИТЕЛЬНО не хочу делать это кнопка за кнопкой.
Спасибо за ваше время, я надеюсь, вы понимаете мой вопрос 🙂
Вы можете сделать это простым способом, я объяснил почти все в коде, но если у вас есть какие-либо вопросы по этому поводу, не стесняйтесь спрашивать, и, пожалуйста, примите этот ответ, если это решило вашу проблему 🙂
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.pixelSelectdef 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()
Также, если вы хотите отобразить простое квадратное изображение поверх изображения сетки, посмотрите на вопрос / решение, которое у меня было: QGraphicsPixmapItem не будет отображаться поверх другого QGraphicsPixmapItem
Если вам действительно не нужен внешний вид кнопок, я бы создал подкласс QWidget, который реализует пользовательский paintEvent и отображает сетку необходимого размера (с учетом размера виджета). Затем в событиях мыши (вверх, вниз, перемещение и т. Д.) Вы можете рассчитать элемент сетки, по которому щелкнули, с помощью простой формулы. Вы можете визуализировать ячейки с разными цветами для обозначения выделения или выделения.
П.С .: Мне бы очень хотелось опубликовать некоторый код из моих реализаций (я делал это два или три раза), но исходные коды есть в моей старой компании 🙂
Вы просто создаете свой собственный QGridLayout, чтобы можно было легко добавлять кнопки.
Я разместил ответ на другой вопрос, показывая, как последовательно заполнять пользовательский QGridLayout связкой виджетов. Кнопки добавляются в соответствии с указанным вами максимальным количеством столбцов. (Примечание: это просто очень грубый пример, но достаточно для начала)
В вашем примере вы бы создали пользовательский макет сетки с 16 столбцами и просто добавили свои кнопки.
Чтобы узнать, какая кнопка была нажата (и сделать подключение проще), вы можете использовать QSignalMapper.
Для исследования задержки вы можете проверить количество (GDI- / User-) дескрипторов вашего приложения (например, с помощью ProcessExplorer). Количество дескрипторов не должно быть выше 10.000.
Я не знаю, почему вы не можете включить кнопки.