Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10

Как сделать так чтобы QPushButton.move работал несколько раз

31.10.2020, 13:15. Показов 1348. Ответов 13

Студворк — интернет-сервис помощи студентам
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
 
 
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.x = 0
        self.y = 0
        self.setupUI()
 
    def setupUI(self):
        self.setGeometry(500, 250, 500, 250)
        self.setWindowTitle('Пример')
        self.btn1 = QPushButton('btn1', self)
        self.btn1.resize(50, 20)
        self.btn1.move(self.x, self.y)
        self.btn2 = QPushButton('btn2', self)
        self.btn2.resize(50, 20)
        self.btn2.move(self.x, self.y + 20)
        self.btn3 = QPushButton('btn3', self)
        self.btn3.resize(50, 20)
        self.btn3.move(self.x, self.y + 40)
        self.main_btn = QPushButton('main', self)
        self.main_btn.resize(100, 50)
        self.main_btn.move(150, 200)
        self.main_btn.clicked.connect(self.move)
 
    def move(self):
        self.x += 10
        self.setupUI()
 
 
app = QApplication(sys.argv)
ex = Example()
ex.show()
exit(app.exec_())
Как сделать так чтобы btn.move срабатывал каждый раз когда мы вызываем setupUI?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.10.2020, 13:15
Ответы с готовыми решениями:

Как сделать чтобы при нажатии на Кнопку (QPushButton), каждый раз выводился разный текст по порядку?
Как сделать чтобы при нажатии на Кнопку(QPushButton), каждый раз выводился разный текст на QLabel по порядку. Просто каждый раз при нажатии...

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

Как сделать так чтобы считывался пробел и не выводились несколько раз повторенные символы
Как сделать так чтобы считывался пробел и не выводились несколько раз повторенные символы Вот код программы: ...

13
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
31.10.2020, 14:19
Cilc, ты лучше скажи - чего ты хочешь этим добиться? А то эти действия выглядят, мягко говоря, странно.
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 15:55  [ТС]
Цитата Сообщение от iSmokeJC Посмотреть сообщение
Cilc, ты лучше скажи - чего ты хочешь этим добиться? А то эти действия выглядят, мягко говоря, странно.
Требуется перемещать кнопки, когда меняется значение.
0
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
31.10.2020, 16:01
Cilc, а зачем каждый раз весь УЙ перерисовывать?
Пример, с минимумом правок твоего кода
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
 
 
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.x = 0
        self.y = 0
        self.setupUI()
 
    def setupUI(self):
        self.setGeometry(500, 250, 500, 250)
        self.setWindowTitle('Пример')
        self.main_btn = QPushButton('main', self)
        self.main_btn.resize(100, 50)
        self.main_btn.move(self.x, self.y)
        self.main_btn.clicked.connect(self.move)
 
    def move(self, x):
        self.x += 10
        self.y += 10
        self.main_btn.move(self.x, self.y)
 
 
app = QApplication(sys.argv)
ex = Example()
ex.show()
exit(app.exec_())
1
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 16:14  [ТС]
Цитата Сообщение от iSmokeJC Посмотреть сообщение
Cilc, а зачем каждый раз весь УЙ перерисовывать?
Пример, с минимумом правок твоего кода
Тогда другой вопрос, код делает играбельное поле для пятнашек, 1-ая боковая кнопка сохранения текущего поля, 2-ая загрузка, 3-ья новое. Проблема в том что когда мы создаем поле другого размера кнопки перемещаются только один раз. То есть было поле 5*5 потом поставили 4*4 -- код работает нормально, кнопки подстроились под формат, но если далее поставить поле другого размера кнопки остаются на своих местах, вопрос, где я обосрался?
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import sys
import random, sys, pymorphy2, webbrowser
from PyQt5 import QtGui
from PyQt5.QtGui import QPainter, QIcon
from PyQt5.QtWidgets import QApplication, QMessageBox, QWidget, QInputDialog, QPushButton, QFileDialog
from PyQt5.QtCore import QSize, Qt
 
 
class gg(QWidget):
    def __init__(self):
        super().__init__()
        self.load_fl = False
        self.have_size = False
        self.setupUI()
 
    def setupUI(self):
        if self.have_size:
            self.matrix = []
            self.have_size = False
        elif self.load_fl is False:
            self.matrix = []
            self.new_field_dialog()
        self.setWindowTitle('Пятнашки')
        self.cell_size = 100
        self.empty = self.size * self.size
        if len(self.matrix) == 0:
            self.matrix_create()
        self.setFixedSize(self.cell_size * self.size + 50, self.cell_size * self.size)
 
        self.save_btn = QPushButton(self)
        self.save_btn.move(self.cell_size * self.size, 0)
        self.save_btn.resize(50, 50)
        self.save_btn.setIcon(QIcon('save_im.png'))
        self.save_btn.setIconSize(QSize(40, 40))
        self.save_btn.clicked.connect(self.save)
 
        self.load_btn = QPushButton(self)
        self.load_btn.move(self.cell_size * self.size, 50)
        self.load_btn.resize(50, 50)
        self.load_btn.setIcon(QIcon('load_im.png'))
        self.load_btn.setIconSize(QSize(40, 40))
        self.load_btn.clicked.connect(self.load)
 
        self.doc_btn = QPushButton(self)
        self.doc_btn.move(self.cell_size * self.size, 150)
        self.doc_btn.resize(50, 50)
        self.doc_btn.setIcon(QIcon('doc_im.png'))
        self.doc_btn.setIconSize(QSize(40, 40))
        self.doc_btn.clicked.connect(lambda: webbrowser.open('https://www.logozavr.ru/1640/'))
 
        self.new_btn = QPushButton(self)
        self.new_btn.move(self.cell_size * self.size, 100)
        self.new_btn.resize(50, 50)
        self.new_btn.setIcon(QIcon('new_im.png'))
        self.new_btn.setIconSize(QSize(40, 40))
        self.new_btn.clicked.connect(self.new_f)
 
    def new_f(self):
        self.new_field_dialog()
        self.have_size = True
        self.load_btn.move(self.cell_size * self.size, 50)
        self.save_btn.move(self.cell_size * self.size, 0)
        self.doc_btn.move(self.cell_size * self.size, 150)
        self.new_btn.move(self.cell_size * self.size, 100)
        self.setupUI()
 
    def save(self):
        try:
            fileName = QFileDialog.getSaveFileName(self, 'Save file')
            if fileName:
                f = open(fileName[0], 'w')
                f.write(str(self.matrix)[1:-1])
        except Exception:
            pass
 
    def load(self):
        try:
            fname = QFileDialog.getOpenFileName(self, 'Open file')
            f = open(fname[0], 'r').read().split('], ')
            self.matrix = []
            for i in f:
                if i == f[-1]:
                    i = i[1:-1].split(', ')
                else:
                    i = i[1:].split(', ')
                lst = [int(j) for j in i]
                self.matrix.append(lst)
            self.size = len(self.matrix[0])
            self.load_btn.move(self.cell_size * self.size, 50)
            self.save_btn.move(self.cell_size * self.size, 0)
            self.doc_btn.move(self.cell_size * self.size, 150)
            self.new_btn.move(self.cell_size * self.size, 100)
            self.load_fl = True
            self.setupUI()
        except Exception:
            pass
 
    def matrix_create(self):
        self.n = 0
        cells_value = list(range(1, self.size * self.size))
        random.shuffle(cells_value)
        cells_value.append(self.empty)
        self.matrix = []
        for i in range(self.size):
            lst = []
            for j in range(self.size):
                lst.append(cells_value.pop(0))
            self.matrix.append(lst)
 
    def mouseReleaseEvent(self, event):
        pos = event.pos()
        y = pos.x() // self.cell_size
        x = pos.y() // self.cell_size
        def cell_find(x, y):
            try:
                if x < 0 or y < 0:
                    raise IndexError
                return self.matrix[x][y], x, y
            except IndexError:
                return None
        try:
            near_cells = [
                cell_find(x - 1, y),
                cell_find(x + 1, y),
                cell_find(x, y - 1),
                cell_find(x, y + 1)]
            empty_cell = []
            for i in near_cells:
                if i is not None and i[0] == self.empty:
                    empty_cell.append(i)
            if len(empty_cell) > 0:
                value = cell_find(x, y)[0]
                empty_value, x2, y2 = empty_cell[0]
                self.matrix[x][y] = empty_value
                self.matrix[x2][y2] = value
                lst = []
                for row in self.matrix:
                    for j in row:
                        lst.append(j)
                lst.pop()
                self.n += 1
                word = pymorphy2.MorphAnalyzer().parse('ход')[0]
                w = word.make_agree_with_number(self.n).word
                if lst == list(range(1, self.size * self.size)):
                    vict_massage = QMessageBox(self)
                    vict_massage.information(self, 'Victory', 'Ура, вы сделали это,' + '\n'
                                                                                       'на это у вас ушло ' + str(
                        self.n) + ' ' + w + '!')
                    self.matrix_create()
            self.update()
        except IndexError:
            pass
 
    def new_field_dialog(self):
       try:
           text, ok = QInputDialog.getText(self, 'Ввод размера', 'Введи число от 3 до 10 (размер поля)')
           if ok:
               self.size = int(text)
               if self.size < 3 or self.size > 10:
                   raise ValueError
           else:
               exit()
       except ValueError:
           error_m = QMessageBox(self)
           error_m.information(self, 'error', 'Неверный ввод, попробуйте снова.')
           self.new_field_dialog()
 
    def paintEvent(self, event):
        qp = QPainter(self)
        qp.setPen(QtGui.QColor('black'))
        for i, row in enumerate(self.matrix):
            y = i * self.cell_size
            for j, value in enumerate(row):
                x = j * self.cell_size
                if value == self.empty:
                    qp.setBrush(QtGui.QColor('white'))
                else:
                    qp.setBrush(QtGui.QColor('green'))
                qp.drawRect(x, y, self.cell_size, self.cell_size)
                if value != self.empty:
                    text = str(value)
                else:
                    text = ''
                qp.drawText(x, y, self.cell_size, self.cell_size, Qt.AlignCenter, text)
 
 
app = QApplication(sys.argv)
ex = gg()
ex.show()
exit(app.exec_())
0
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
31.10.2020, 16:19
Cilc, надо использовать менеджеры компоновки, т.н. Layout'ы, вместо жесткого указания координат.
Тогда изменения размеров окна, поля и т.д. не будут иметь значения, виджеты будут выстраиваться согласно заданной компоновки.
1
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 16:23  [ТС]
iSmokeJC, не понял, как это можно организовать?
0
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
31.10.2020, 16:25
https://pythonworld.ru/gui/pyqt5-layout.html
0
2 / 2 / 0
Регистрация: 21.06.2020
Сообщений: 97
31.10.2020, 16:28
Цитата Сообщение от Cilc Посмотреть сообщение
iSmokeJC, не понял, как это можно организовать?
Он имеет ввиду, что либо использовать слои - Layout, которые сами изменяют размер и положение виджета, относительно измененного размера окна.
Либо вручную прописывать ResizeEvent, где ты задаешь не абсолютное позиционирование, а каждый раз берешь новый размер окна и рассчитываешь положение/размер виджета, относительно него
1
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 16:56  [ТС]
Тогда вопрос как в layout изменить размеры кнопок(сделать их квадратными)?
0
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
31.10.2020, 17:00
setFixedSize(width, height)
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 17:24  [ТС]
Цитата Сообщение от ShaunDMoon Посмотреть сообщение
вручную прописывать ResizeEvent, где ты задаешь не абсолютное позиционирование, а каждый раз берешь новый размер окна и рассчитываешь положение/размер виджета, относительно него
Попробовал добавить
Python
1
2
3
4
5
    def resizeEvent(self, a0: QtGui.QResizeEvent):
        self.load_btn.move(self.cell_size * self.size, 50)
        self.save_btn.move(self.cell_size * self.size, 0)
        self.doc_btn.move(self.cell_size * self.size, 150)
        self.new_btn.move(self.cell_size * self.size, 100)
Проблема осталась, что можно сделать?
0
2 / 2 / 0
Регистрация: 21.06.2020
Сообщений: 97
31.10.2020, 17:45
Цитата Сообщение от Cilc Посмотреть сообщение
Попробовал добавить
Python
1
2
3
4
5
    def resizeEvent(self, a0: QtGui.QResizeEvent):
        self.load_btn.move(self.cell_size * self.size, 50)
        self.save_btn.move(self.cell_size * self.size, 0)
        self.doc_btn.move(self.cell_size * self.size, 150)
        self.new_btn.move(self.cell_size * self.size, 100)
Проблема осталась, что можно сделать?
Нет, это по-прежнему абсолютное позиционирование. self.cell_size и self.size - это константы. Они не меняются. Если же self.size - это атрибут QWidget, то он содержит класс QSize, а не значение в пикселях. (Возможно я сейчас глупость сказал, но во всяком случае. Это не так работает)
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 10
31.10.2020, 17:57  [ТС]
Цитата Сообщение от ShaunDMoon Посмотреть сообщение
Нет, это по-прежнему абсолютное позиционирование
Ладно, возвращаемся к Layout-ам. Никак не могу понять как нормально позиционировать кнопки внутри layout-а. Да и вообще их позиционирование
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.10.2020, 17:57
Помогаю со студенческими работами здесь

Сделать так, чтобы можно было добавить несколько одинаковых блюд, не кликая несколько раз
Ребята, подскажите! На форме2 надо сделать так, чтобы можно было добавить несколько одинаковых блюд, не кликая несколько раз, а чтобы в...

Как сделать так, чтобы код работал с матрицей 4*4?
Добрый день. У меня есть код, который с помощью метода Гаусса решает СЛАУ. Как его модифицировать таким образом, чтобы он работал с...

Как сделать так, чтобы батник работал с несколькими файлами?
Проблема в бат-файле. Как сделать так, чтобы батник работал на несколько файлов? Вот код: pushd c:\RKC\OUT\ C:\RKC\debase\xml fo %1...

Можно ли сделать так чтобы скрипты выполнялись несколько раз через определенное время?
Можно ли сделать так чтобы скрипты выполнялись несколько раз через определенное время.

Как сделать так, чтобы бот работал независимо с каждым пользователем?
Пишу бота ВК для системы pomodoro, по сути представляет из себя таймер. Реализовал его через time.delay, но в таком случае, если во время...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru